3

ユーザーの連絡先情報を保存する必要があります。このデータをhCardとしてページに表示し、 vCardとしてダウンロード可能にしたいと考えています。また、電話番号、メールなどでデータベースを検索できるようにしたいと思います。

このデータを保存する最良の方法は何だと思いますか? ユーザーは複数のアドレスを持つことができるため、完全な正規化は混乱します。XML の使用を考えていますが、XML db フィールドのクエリに慣れていません。連絡先情報でユーザーを検索することはできますか?

問題があれば、SQL Server 2005 を使用しています。

4

7 に答える 7

7

People とその住所の 2 つのテーブルを考えてみましょう。

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 には 2 つの住所があります。1 つは「自宅」で、もう 1 つは「職場」です。Peopleこれら 2 つのうちの 1 つは、primaryAddressTag 列の外部キー (相互参照のように) として記録できます (そして記録する必要があります) 。

Spock には、「other」というタグが付いた単一のアドレスがあります。primaryAddressTagそれが Spock の唯一のアドレスであるため、pid=2の列には「other」という値を入力する必要があります。

このスキーマには、同じ人が誤ってタグを再利用して自分のアドレスを複製するのを防ぐと同時に、他のすべての人が好きなアドレス タグを使用できるようにするという優れた効果があります。

さらに、 の FK 参照を使用するprimaryAddressTagと、データベース システム自体が (データベース オタクが参照整合性と呼ぶものを介して) プライマリ アドレス タグの有効性を強制するため、アプリケーションが (またはすべての) アプリケーションがそれについて心配する必要はありません。

于 2008-09-14T03:34:11.817 に答える
3

なぜ完全な正規化は「混乱する」のでしょうか?これはまさに、正規化によって煩雑さが軽減されるようなものです。

于 2008-09-01T21:36:57.473 に答える
3

データの正規化を恐れないでください。ジョンが言及しているように、正規化は問題ではなく解決策です。いくつかの結合を避けるためだけにデータを非正規化しようとすると、将来深刻な問題を引き起こすことになります。妥当なサイズのデータ​​セットを取得した後で、この種のデータをリファクタリングしようとしても楽しくありません。

Highrise from 36 Signalsをチェックすることを強くお勧めします。最近、オンライン連絡先マネージャーを探していたときに勧められました。それはとても正しいことです。実際のところ、このサービスに対する私の唯一の異議は、有料版は高すぎるということです。それだけです。

今日の状況では、私は平坦な住所プロファイルには適合しません。定期的に使用する電子メール アドレスが 4 ~ 5 個、電話番号が 5 個、アドレスが 3 個、いくつかの Web サイトと IM プロファイルがあり、それらすべてを連絡先プロファイルに含めます。連絡先管理システムを今構築し始めていて、アーキテクチャ上の制限 (Gmail のカンタクトが 1 つの電子メール アドレスにキー設定されていることを考えてください) に悩まされていない場合は、ユーザーに有利に働き、連絡先構造をできるだけ柔軟 (標準化) にしてください。可能。

乾杯、-D。

于 2008-11-16T03:19:10.013 に答える
1

私はSQLiteを知っていますが、それは実際には役に立ちません-このデータを格納するための(データベースに関係なく)最適なスキーマを見つけることについて話しているのです。

于 2008-09-01T21:09:01.423 に答える
1

ジョンによると、古典的な正規化されたスキーマの問題が何であるかはわかりません。あなたは続けるための多くの情報を提供していませんが、ユーザーとアドレスの間には1対多の関係があると言っているので、アドレス関係でユーザーへの外部キーを使用した沼地の標準ソリューションにふっくらしたいと思います.

于 2008-09-01T23:32:44.590 に答える
0

各ユーザーが 1 つまたは複数のアドレス、電話番号などを持っていると仮定すると、「ユーザー」テーブル、「アドレス テーブル」(主キーとユーザーへの一意でない参照を含む) を持つことができます。電話番号 - 同じ UserID 外部キーを持つ複数の行を許可します。これにより、「ユーザー X のすべてのアドレス」のクエリが非常に簡単になります。

于 2008-09-01T23:36:53.940 に答える
0

スクリプトはありませんが、使用できる mySQL はあります。その前に、vCard を SQL に格納するには 2 つの論理的なアプローチがあるように思われることを述べておく必要があります。

  1. カード全体を保存し、データベースに (おそらく) 巨大なテキスト文字列を検索させ、それらをコードの別の部分またはクライアント側で処理します。例えば

    CREATE TABLE IF NOT EXISTS vcards(
    name_or_lettervarchar(250) NOT NULL,
    vcardtext NOT NULL,
    timestamptimestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
    PRIMARY KEY ( username)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

おそらく実装は簡単ですが (データで何をしているかによって異なります)、多くのエントリがあると検索が遅くなります。これがあなたのためだけなら、これはうまくいくかもしれません(それが良いのであれば、それはあなたのためだけではありません.あなたと。)

私は vCard の進化を見てきましたが、将来 /some/ 時に何らかの変更があることを知っているので、3 つのテーブルを使用します。

1 つ目はカードです (これは主に私の既存のテーブルにリンクされています。これが必要ない場合は、カット ダウン バージョンにすることができます)。2 つ目はカードの定義です (vCard ではプロファイルと呼ばれているようです)。最後は、カードのすべての実際のデータです。

私は DBIx::Class (はい、私はその 1 人です) にすべてのデータベース作業を任せているので、(3 つのテーブル) は私にとってはかなりうまく機能しているように見えます (もちろん、rfc2426に一致するように型を強化することはできますが)ただし、ほとんどの場合、各データは単なるテキスト文字列です。)

個人の住所を正規化しない理由は、データベースに既に住所テーブルがあり、これら 3 つはユーザー以外の連絡先の詳細のためだけにあるためです。

 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 ではありませんが、お役に立てば幸いです。

于 2012-07-03T14:32:30.677 に答える