주소록 DB 스키마
-
09-06-2019 - |
해결책
사람과 해당 주소에 대한 두 개의 테이블을 고려하십시오.
People (pid, prefix, firstName, lastName, suffix, DOB, ... primaryAddressTag )
AddressBook (pid, tag, address1, address2, city, stateProv, postalCode, ... )
People의 기본 키(각 행을 고유하게 식별하는)는 다음과 같습니다. pid
.AddressBook의 PK는 pid와 tag의 구성입니다. (pid, tag)
.
몇 가지 예시 데이터:
사람들
1, Kirk
2, Spock
주소록
1, home, '123 Main Street', Iowa
1, work, 'USS Enterprise NCC-1701'
2, other, 'Mt. Selaya, Vulcan'
이 예에서 Kirk에는 두 개의 주소가 있습니다.하나는 '집'이고 하나는 '직장'입니다.이 둘 중 하나는 상호 참조와 같은 외래 키로 기록될 수 있고 그래야 합니다. People
PrimaryAddressTag 열에 있습니다.
Spock은 'other' 태그가 붙은 단일 주소를 가지고 있습니다.이것이 Spock의 유일한 주소이므로 'other' 값은 primaryAddressTag
pid=2에 대한 열입니다.
이 스키마는 동일한 사람이 실수로 태그를 재사용하여 자신의 주소를 복제하는 것을 방지하는 동시에 다른 모든 사람이 원하는 주소 태그를 사용할 수 있도록 하는 좋은 효과를 제공합니다.
또한 FK 참조를 사용하면 primaryAddressTag
, 데이터베이스 시스템 자체는 (데이터베이스 괴짜들이 참조 무결성이라고 부르는 것을 통해) 기본 주소 태그의 유효성을 시행하므로 귀하의 응용 프로그램 또는 다른 응용 프로그램이 이에 대해 걱정할 필요가 없습니다.
다른 팁
완전한 정규화가 왜 "엉망"이 될까요?이것이 바로 정규화가 덜 지저분해지는 종류의 것입니다.
데이터 정규화를 두려워하지 마세요.정규화 존은 언급한다, 해결책은 문제가 아닙니다.단지 몇 번의 조인을 피하기 위해 데이터를 비정규화하려고 하면 나중에 심각한 문제가 발생할 수 있습니다.합리적인 크기의 데이터세트를 확보한 후에 이러한 종류의 데이터를 리팩터링하는 것은 재미없을 것입니다.
꼭 확인해 보시기 바랍니다. 고층 건물 36개의 신호에서.최근 온라인 연락처 관리자를 찾을 때 추천받았습니다.정말 많은 일을 합니다.사실, 지금까지 이 서비스에 대한 유일한 반대 의견은 유료 버전이 너무 비싸다는 것입니다. 그게 전부입니다.
현재 상황으로는 저는 평면적인 주소 프로필에 맞지 않습니다.나는 정기적으로 사용하는 4-5개의 전자 메일 주소, 5개의 전화 번호, 3개의 주소, 여러 웹 사이트 및 IM 프로필을 가지고 있으며 모두 내 연락처 프로필에 포함합니다.지금 연락처 관리 시스템을 구축하기 시작했고 아키텍처 제한(Gmail이 단일 이메일 주소로 입력될 수 없다고 생각)으로 인해 방해받지 않는다면 사용자에게 호의를 베풀고 연락처 구조를 다음과 같이 유연하게(정규화) 만드십시오. 가능한.
건배, -D.
저는 SQLite에 대해 알고 있지만 실제로는 도움이 되지 않습니다. 저는 이 데이터를 저장하기 위한 최상의 스키마(데이터베이스에 관계없이)를 알아내는 것에 대해 이야기하고 있습니다.
John에 따르면, 고전적인 정규화된 스키마의 문제점이 무엇인지 알 수 없습니다.계속할 정보를 많이 제공하지 않았지만 사용자와 주소 사이에 일대다 관계가 있다고 말했기 때문에 주소 관계에서 사용자에 대한 외래 키가 있는 bog 표준 솔루션을 사용하겠습니다.
각 사용자가 하나 이상의 주소, 전화번호 등을 가지고 있다고 가정하면 '사용자' 테이블, '주소 테이블'(기본 키와 사용자에 대한 고유하지 않은 참조 포함)을 가질 수 있습니다. 전화 번호 - 동일한 UserID 외래 키를 사용하여 여러 행을 허용하므로 '사용자 X의 모든 주소' 쿼리가 매우 간단해집니다.
스크립트는 없지만 사용할 수 있는 mySQL은 있습니다.그 전에 SQL에 vCard를 저장하는 데에는 두 가지 논리적 접근 방식이 있다는 점을 언급해야 합니다.
전체 카드를 저장하고 데이터베이스가 (아마도) 거대한 텍스트 문자열을 검색하여 코드의 다른 부분이나 클라이언트 측에서 처리하도록 하세요.예를 들어
존재하지 않는 경우 테이블 생성
vcards
(
name_or_letter
varchar(250) NULL이 아닙니다.
vcard
텍스트는 NULL이 아닙니다.
timestamp
CURRENT_TIMESTAMP 업데이트 시 타임스탬프 기본값 CURRENT_TIMESTAMP,
기본 키(username
)
) 엔진=MyISAM 기본 CHARSET=utf8 COLLATE=utf8_bin;
아마도 구현하기 쉬울 것입니다(데이터로 수행하는 작업에 따라 다름). 항목이 많으면 검색 속도가 느려질 수 있습니다.이것이 당신을 위한 것이라면 효과가 있을 것입니다. 절대 당신만을 위한 것입니다.) 그런 다음 귀하가 공유하는(또는 다른 사람이 귀하와 공유하는) 아름다운 모듈을 사용하여 vCard 클라이언트 측 또는 서버 측을 처리할 수 있습니다.
나는 vCard가 발전하는 것을 지켜봤고 알다 앞으로 / 시간 / 시간에 약간의 변화가있을 것이므로 세 테이블을 사용합니다.
첫 번째는 카드입니다. (이것은 주로 기존 테이블로 다시 연결됩니다. 이 카드가 필요하지 않은 경우 축소 버전이 될 수 있습니다.)두 번째는 카드 정의입니다(vCard에서는 프로필이라고 하는 것으로 보입니다).마지막은 카드의 모든 실제 데이터입니다.
dbix :: class, (예, 나는 그 중 하나입니다) 모든 데이터베이스가 작동하게하기 때문에 (세 테이블)는 나에게 잘 작동하는 것 같습니다. RFC2426 더 가깝지만 대부분의 경우 각 데이터 조각은 단지 텍스트 문자열입니다.)
사람으로부터 주소를 정상화하지 않는 이유는 이미 데이터베이스에 주소 테이블이 있고이 세 가지는 사용자가 아닌 연락처 세부 사항에 대한 것이기 때문입니다.
CREATE TABLE `vCards` (
`card_id` int(255) unsigned NOT NULL AUTO_INCREMENT,
`card_peid` int(255) DEFAULT NULL COMMENT 'link back to user table',
`card_acid` int(255) DEFAULT NULL COMMENT 'link back to account table',
`card_language` varchar(5) DEFAULT NULL COMMENT 'en en_GB',
`card_encoding` varchar(32) DEFAULT 'UTF-8' COMMENT 'why use anything else?',
`card_created` datetime NOT NULL,
`card_updated` datetime NOT NULL,
PRIMARY KEY (`card_id`) )
ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='These are the contact cards'
create table vCard_profile (
vcprofile_id int(255) unsigned auto_increment NOT NULL,
vcprofile_version enum('rfc2426') DEFAULT "rfc2426" COMMENT "defaults to vCard 3.0",
vcprofile_feature char(16) COMMENT "FN to CATEGORIES",
vcprofile_type enum('text','bin') DEFAULT "text" COMMENT "if it is too large for vcd_value then user vcd_bin",
PRIMARY KEY (`vcprofile_id`)
) COMMENT "These are the valid types of card entry";
INSERT INTO vCard_profile VALUES('','rfc2426','FN','text'),('','rfc2426','N','text'),('','rfc2426','NICKNAME','text'),('','rfc2426','PHOTO','bin'),('','rfc2426','BDAY','text'),('','rfc2426','ADR','text'),('','rfc2426','LABEL','text'),('','rfc2426','TEL','text'),('','rfc2426','EMAIL','text'),('','rfc2426','MAILER','text'),('','rfc2426','TZ','text'),('','rfc2426','GEO','text'),('','rfc2426','TITLE','text'),('','rfc2426','ROLE','text'),('','rfc2426','LOGO','bin'),('','rfc2426','AGENT','text'),('','rfc2426','ORG','text'),('','rfc2426','CATEGORIES','text'),('','rfc2426','NOTE','text'),('','rfc2426','PRODID','text'),('','rfc2426','REV','text'),('','rfc2426','SORT-STRING','text'),('','rfc2426','SOUND','bin'),('','rfc2426','UID','text'),('','rfc2426','URL','text'),('','rfc2426','VERSION','text'),('','rfc2426','CLASS','text'),('','rfc2426','KEY','bin');
create table vCard_data (
vcd_id int(255) unsigned auto_increment NOT NULL,
vcd_card_id int(255) NOT NULL,
vcd_profile_id int(255) NOT NULL,
vcd_prof_detail varchar(255) COMMENT "work,home,preferred,order for e.g. multiple email addresses",
vcd_value varchar(255),
vcd_bin blob COMMENT "for when varchar(255) is too small",
PRIMARY KEY (`vcd_id`)
) COMMENT "The actual vCard data";
이것은 최고의 SQL은 아니지만 도움이 되기를 바랍니다.