سؤال

أحتاج إلى تخزين معلومات الاتصال للمستخدمين.أريد تقديم هذه البيانات على الصفحة كملف hCard وقابلة للتنزيل كـ a vCard.أود أيضًا أن أتمكن من البحث في قاعدة البيانات عن طريق رقم الهاتف أو البريد الإلكتروني وما إلى ذلك.

ما رأيك في أفضل طريقة لتخزين هذه البيانات؟وبما أن المستخدمين يمكن أن يكون لديهم عناوين متعددة، فإن التسوية الكاملة ستكون فوضى.أفكر في استخدام XML، لكني لست على دراية بالاستعلام عن حقول XML db.هل سأظل قادرًا على البحث عن المستخدمين من خلال معلومات الاتصال؟

أنا أستخدم SQL Server 2005، إذا كان ذلك مهمًا.

هل كانت مفيدة؟

المحلول

فكر في جدولين للأشخاص وعناوينهم:

People (pid, prefix, firstName, lastName, suffix, DOB, ... primaryAddressTag )

AddressBook (pid, tag, address1, address2, city, stateProv, postalCode, ... )

المفتاح الأساسي (الذي يحدد كل صف بشكل فريد) للأشخاص هو pid.PK الخاص بـ AddressBook هو تكوين معرف المنتج والعلامة (pid, tag).

بعض البيانات النموذجية:

الناس

1, Kirk

2, Spock

دليل العناوين

1, home, '123 Main Street', Iowa

1, work, 'USS Enterprise NCC-1701'

2, other, 'Mt. Selaya, Vulcan'

في هذا المثال، لدى كيرك عنوانين:"منزل" و"عمل" واحد.يمكن (ويجب) الإشارة إلى أحد هذين الاثنين كمفتاح خارجي (مثل الإسناد الترافقي) في People في العمود PrimaryAddressTag.

لدى Spock عنوانًا واحدًا يحمل العلامة "other".نظرًا لأن هذا هو عنوان Spock الوحيد، فيجب إدخال القيمة "other" في ملف primaryAddressTag عمود للمعرف = 2.

يتمتع هذا المخطط بتأثير جيد يتمثل في منع نفس الشخص من تكرار أي من عناوينه الخاصة عن طريق إعادة استخدام العلامات عن طريق الخطأ بينما يسمح في نفس الوقت لجميع الأشخاص الآخرين باستخدام أي علامات عنوان يريدونها.

علاوة على ذلك، مع مراجع FK في primaryAddressTag, ، فإن نظام قاعدة البيانات نفسه سيفرض صلاحية علامة العنوان الأساسية (عبر شيء نسميه خبراء قاعدة البيانات التكامل المرجعي) بحيث لا داعي للقلق بشأن تطبيقك - أو أي تطبيق آخر.

نصائح أخرى

لماذا قد يكون التطبيع الكامل "فوضى"؟هذا هو بالضبط الشيء الذي يجعل التطبيع أقل فوضى.

لا تخف من تطبيع بياناتك.التطبيع مثل يذكر جون, ، هو الحل وليس المشكلة.إذا حاولت إلغاء تسوية بياناتك فقط لتجنب انضمام زوجين، فسوف تسبب لنفسك مشكلة خطيرة في المستقبل.إن محاولة إعادة هيكلة هذا النوع من البيانات بعد أن يكون لديك مجموعة بيانات ذات حجم معقول لن تكون ممتعة.

أقترح عليك بشدة التحقق من ذلك إرتفاع عالى من 36 إشارة.لقد أوصيت به مؤخرًا عندما كنت أبحث عن مدير اتصال عبر الإنترنت.إنه يفعل الكثير من الصواب.في الواقع، اعتراضي الوحيد حتى الآن على الخدمة هو أنني أعتقد أن الإصدارات المدفوعة باهظة الثمن - هذا كل شيء.

في ظل الظروف الحالية، لا أنسب إلى ملف تعريف العنوان الثابت.لدي 4-5 عناوين بريد إلكتروني أستخدمها بانتظام، و5 أرقام هواتف، و3 عناوين، والعديد من مواقع الويب وملفات تعريف المراسلة الفورية، والتي أود تضمينها جميعًا في ملف تعريف جهة الاتصال الخاص بي.إذا كنت تبدأ الآن في إنشاء نظام لإدارة جهات الاتصال ولم تكن مقيدًا بالقيود المعمارية (فكر في أن عناوين Gmail مرتبطة بعنوان بريد إلكتروني واحد)، فافعل معروفًا للمستخدمين واجعل بنية الاتصال الخاصة بك مرنة (طبيعية) مثل ممكن.

بصحتك،-د.

أنا على دراية بـ SQLite، لكن هذا لا يساعد حقًا - أنا أتحدث عن اكتشاف أفضل مخطط (بغض النظر عن قاعدة البيانات) لتخزين هذه البيانات.

لكل جون، لا أرى ما هي المشكلة في المخطط المطبيع الكلاسيكي.لم تقدم الكثير من المعلومات للمضي قدمًا، لكنك تقول أن هناك علاقة رأس بأطراف بين المستخدمين والعناوين، لذا فإنني أقترح حلًا قياسيًا للمستنقع باستخدام مفتاح خارجي للمستخدم في علاقة العنوان.

إذا افترضت أن كل مستخدم لديه عنوان واحد أو أكثر، ورقم هاتف، وما إلى ذلك، فقد يكون لديك جدول "المستخدمون"، و"جدول العناوين" (يحتوي على مفتاح أساسي ثم مرجع غير فريد للمستخدمين)، والشيء نفسه بالنسبة أرقام الهواتف - السماح بصفوف متعددة بنفس المفتاح الخارجي لمعرف المستخدم، مما يجعل الاستعلام عن "جميع العناوين للمستخدم X" أمرًا بسيطًا للغاية.

ليس لدي برنامج نصي، ولكن لدي قاعدة بيانات MySQL التي يمكنك استخدامها.قبل ذلك يجب أن أذكر أنه يبدو أن هناك طريقتين منطقيتين لتخزين vCards في SQL:

  1. قم بتخزين البطاقة بأكملها ودع قاعدة البيانات تبحث (ربما) عن سلاسل نصية ضخمة، وتعالجها في جزء آخر من التعليمات البرمجية الخاصة بك أو حتى من جانب العميل.على سبيل المثال

    إنشاء جدول إذا لم يكن موجودا vcards (
    name_or_letter فارشار (250) ليس فارغًا،
    vcard النص ليس فارغًا،
    timestamp الطابع الزمني الافتراضي CURRENT_TIMESTAMP عند التحديث CURRENT_TIMESTAMP،
    المفتاح الأساسي (username)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

ربما يكون من السهل تنفيذه (اعتمادًا على ما تفعله بالبيانات) على الرغم من أن عمليات البحث الخاصة بك ستكون بطيئة إذا كان لديك العديد من الإدخالات.إذا كان هذا من أجلك فقط، فقد ينجح هذا، (إذا كان جيدًا فهو كذلك.) أبداً من أجلك فقط.) يمكنك بعد ذلك معالجة جانب عميل vCard أو جانب الخادم باستخدام بعض الوحدات الجميلة التي تشاركها (أو يشاركها شخص آخر معك.)

لقد شاهدت تطور vCard و يعرف سيكون هناك بعض التغيير في / بعض الوقت في المستقبل ، لذلك أستخدم ثلاثة جداول.

الأول هو البطاقة، (يرتبط هذا في الغالب بالجداول الموجودة لدي - إذا لم تكن بحاجة إليها، فيمكن أن تكون نسختك نسخة مختصرة).والثاني هو تعريفات البطاقة (والتي يبدو أنها تسمى الملف الشخصي في vCard Speak).والأخير هو كافة البيانات الفعلية للبطاقات.

لأنني تركت DBIX :: (نعم أنا واحد من هؤلاء) أقوم بجميع قاعدة البيانات التي تعمل على هذا ، يبدو (ثلاثة جداول) يعمل بشكل جيد بالنسبة لي ، (على الرغم من أنه من الواضح أنه يمكنك تشديد الأنواع لتتناسب مع 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 ولكن آمل أن يساعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top