Merancang struktur basis data pertemanan: Haruskah saya menggunakan kolom multinilai?

9

Katakanlah saya memiliki tabel yang dipanggil User_FriendList, yang memiliki karakteristik berikut:

CREATE TABLE User_FriendList (
    ID ...,
    User_ID...,
    FriendList_IDs...,
    CONSTRAINT User_Friendlist_PK PRIMARY KEY (ID)
);

Dan mari kita anggap bahwa tabel tersebut menampung data berikut:

 + ---- + --------- + --------------------------- +
 | ID | User_ID | Friendlist_IDs             |
 + ---- + --------- + --------------------------- +
 | 1 | 102 | 2: 15: 66: 35: 26: 17: |
 + ---- + --------- + --------------------------- +
 | 2 | 114 | 1: 12: 63: 33: 24: 16: 102 |
 + ---- + --------- + --------------------------- +
 | 3 | 117 | 6: 24: 52: 61: 23: 90: 97: 118 |
 + ---- + --------- + --------------------------- +

Catatan: ":" (titik dua) adalah pembatas ketika meledak dalam PHP menjadi array.

Pertanyaan

Begitu:

  • Apakah ini cara yang nyaman untuk "menyimpan" IDsdari FriendList?

  • Atau, sebagai gantinya, haruskah saya memiliki baris individual dengan hanya satu FriendIdnilai tunggal di masing-masing dan, ketika saya perlu mengambil semua baris daftar yang diberikan , cukup melakukan query seperti SELECT * FROM UserFriendList WHERE UserId = 1?

Yeln
sumber
3
Saya sarankan Anda membaca ini: stackoverflow.com/questions/3653462/…
tombom
Ini adalah cara yang agak nyaman untuk menyimpan ID, selama Anda tidak berencana melakukan apa pun dengan ID tersebut dan tidak terlalu peduli dengan kualitas data.
mustaccio
Saya pikir codedodle.com/2014/12/social-network-friends-database.html bisa menjadi salah satu solusi terbaik.
Gupta

Jawaban:

19

Mengelola informasi individu

Dengan asumsi bahwa, dalam domain bisnis Anda,

  • seorang Pengguna dapat memiliki nol-satu-atau-banyak Teman ;
  • seorang Teman harus terlebih dahulu terdaftar sebagai Pengguna ; dan
  • Anda akan mencari, dan / atau menambah, dan / atau menghapus, dan / atau memodifikasi, satu nilai dari Daftar Teman ;

maka setiap datum tertentu yang dikumpulkan dalam Friendlist_IDskolom multinilai mewakili sepotong informasi terpisah yang membawa makna yang sangat tepat. Karena itu, kata kolom

  • memerlukan kelompok kendala eksplisit yang tepat, dan
  • nilai-nilainya berpotensi dimanipulasi secara individu melalui beberapa operasi relasional (atau kombinasi daripadanya).

Jawaban singkat

Konsekuensinya, Anda harus mempertahankan masing-masing Friendlist_IDsnilai dalam (a) kolom yang menerima secara eksklusif satu nilai tunggal per baris dalam (b) tabel yang mewakili tipe asosiasi level-konseptual yang dapat terjadi antara Pengguna , yaitu Persahabatan - seperti Saya akan mencontohkan di bagian berikut—.

Dengan cara ini, Anda akan dapat menangani (i) tabel tersebut sebagai relasi matematis dan (ii) kolom tersebut sebagai atribut relasi matematis — tentu saja sebanyak MySQL dan izin dialek SQL-nya—.

Mengapa?

Karena model data relasional , dibuat oleh Dr. E. F. Codd , menuntut memiliki tabel yang terdiri dari kolom yang memiliki tepat satu nilai domain atau tipe yang berlaku per baris; karenanya, mendeklarasikan tabel dengan kolom yang dapat berisi lebih dari satu nilai domain atau tipe yang dimaksud (1) tidak mewakili hubungan matematis dan (2) tidak akan mengizinkan memperoleh keuntungan yang diusulkan dalam kerangka teori yang disebutkan di atas.

Memodelkan Persahabatan antar Pengguna : Mendefinisikan aturan lingkungan bisnis terlebih dahulu

Saya sangat merekomendasikan untuk mulai membuat batasan database - sebelum yang lain - skema konseptual yang sesuai berdasarkan definisi aturan bisnis yang relevan , di antara faktor-faktor lain, harus menggambarkan jenis hubungan timbal balik yang ada di antara berbagai aspek yang menarik, yaitu , tipe entitas yang berlaku dan propertinya ; misalnya:

  • Seorang Pengguna terutama diidentifikasi oleh UserId miliknya
  • Seorang Pengguna secara bergantian diidentifikasi oleh kombinasi FirstName , LastName , Gender , dan Tanggal Lahirnya
  • Seorang Pengguna secara bergantian diidentifikasi oleh Username- nya
  • Sebuah Pengguna adalah Pemohon nol-satu-atau-banyak Friendships
  • Sebuah Pengguna adalah Addressee nol-satu-atau-banyak Friendships
  • Sebuah Persahabatan terutama diidentifikasi oleh kombinasi yang RequesterId dan yang AddresseeId

Diagram Eksposisi IDEF1X

Dengan cara ini, saya dapat memperoleh diagram IDEF1X 1 yang ditunjukkan pada Gambar 1 , yang mengintegrasikan sebagian besar aturan yang dirumuskan sebelumnya:

Gambar 1. User Friendships Diagram IDEF1X

Seperti yang digambarkan, Pemohon dan Penerima adalah denotasi yang menyatakan Peran yang dilakukan oleh Pengguna tertentu yang mengambil bagian dalam Persahabatan tertentu .

Dengan demikian, tipe entitas Persahabatan menggambarkan tipe asosiasi dari banyak-ke-banyak (M: N) rasio kardinalitas yang dapat melibatkan kejadian berbeda dari jenis entitas yang sama , yaitu, Pengguna . Dengan demikian, ini adalah contoh konstruksi klasik yang dikenal sebagai "Bill of Material" atau "Bagian Ledakan".


1 Definisi Integrasi untuk Pemodelan Informasi ( IDEF1X ) adalah teknik yang sangat direkomendasikan yang ditetapkan sebagai standar pada Desember 1993 oleh Institut Nasional Standar dan Teknologi (NIST). Ini didasarkan pada (a) bahan teori awal yang ditulis oleh satu - satunya pencetus model relasional, yaitu, Dr. EF Codd ; pada (b) tampilan entitas-hubungan data, yang dikembangkan oleh Dr. PP Chen ; dan juga pada (c) Teknik Desain Basis Data Logis, yang dibuat oleh Robert G. Brown.


Ilustrasi desain logis SQL-DDL

Kemudian, dari diagram IDEF1X yang disajikan di atas, menyatakan pengaturan DDL seperti yang berikut ini jauh lebih "alami":

-- You should determine which are the most fitting 
-- data types and sizes for all the table columns 
-- depending on your business context characteristics.

-- At the physical level, you should make accurate tests 
-- to define the mostconvenient INDEX strategies based on 
-- the pertinent query tendencies.

-- As one would expect, you are free to make use of 
-- your preferred (or required) naming conventions. 

CREATE TABLE UserProfile ( -- Represents an independent entity type.
    UserId          INT      NOT NULL,
    FirstName       CHAR(30) NOT NULL,
    LastName        CHAR(30) NOT NULL,
    BirthDate       DATE     NOT NULL,
    GenderCode      CHAR(3)  NOT NULL,
    Username        CHAR(20) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT UserProfile_PK  PRIMARY KEY (UserId),
    CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
        FirstName,
        LastName,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT UserProfile_AK2 UNIQUE (Username) -- Single-column ALTERNATE KEY.
);

CREATE TABLE Friendship ( -- Stands for an associative entity type.
    RequesterId     INT      NOT NULL,
    AddresseeId     INT      NOT NULL, -- Fixed with a well-delimited data type.
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT Friendship_PK            PRIMARY KEY (RequesterId, AddresseeId), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipToRequester_FK FOREIGN KEY (RequesterId)
        REFERENCES UserProfile (UserId),
    CONSTRAINT FriendshipToAddressee_FK FOREIGN KEY (AddresseeId)
        REFERENCES UserProfile (UserId)
);

Dengan cara ini:

  • setiap tabel dasar mewakili jenis entitas individual;
  • setiap kolom mewakili properti tunggal dari masing - masing jenis entitas;
  • tipe data tertentu a diperbaiki untuk setiap kolom untuk menjamin bahwa semua nilai yang dikandungnya milik set tertentu dan terdefinisi dengan baik , baik itu INT, DATETIME, CHAR, dll .; dan
  • beberapa kendala b dikonfigurasikan (secara deklaratif) untuk memastikan bahwa asersi dalam bentuk baris yang dipertahankan dalam semua tabel memenuhi aturan bisnis yang ditentukan pada skema konseptual.

Keuntungan dari kolom bernilai tunggal

Seperti yang ditunjukkan, Anda dapat, misalnya:

  • Manfaatkan integritas referensial yang diberlakukan oleh sistem manajemen basis data (DBMS untuk singkatnya) untuk Friendship.AddresseeIdkolom, karena membatasi itu sebagai KUNCI LUAR NEGERI (FK untuk singkatnya) yang membuat referensi ke UserProfile.UserIdkolom menjamin bahwa setiap nilai menunjuk ke baris yang ada .

  • Buat komposit PRIMARY KEY (PK) yang terdiri dari kombinasi kolom (Friendship.RequesterId, Friendship.AddresseeId), membantu membedakan secara elegan semua baris yang disisipkan dan, tentu saja, melindungi keunikannya .

    Tentu saja, ini berarti bahwa lampiran kolom tambahan untuk nilai pengganti yang ditugaskan sistem (misalnya, yang diatur dengan properti IDENTITY di Microsoft SQL Server atau dengan atribut AUTO_INCREMENT di MySQL) dan INDEX yang membantu sepenuhnya sepenuhnya berlebihan .

  • Batasi nilai yang dipertahankan dalam Friendship.AddresseeIdtipe data yang tepat c (yang harus cocok, misalnya yang dibuat untuk UserProfile.UserId, dalam hal ini INT), membiarkan DBMS menangani validasi otomatis yang bersangkutan .

    Faktor ini juga dapat membantu (a) memanfaatkan fungsi tipe bawaan yang sesuai dan (b) mengoptimalkan penggunaan ruang disk .

  • Optimalkan pengambilan data pada tingkat fisik dengan mengkonfigurasi indeks kecil dan cepat untuk Friendship.AddresseeIdkolom, karena elemen-elemen fisik ini dapat secara substansial membantu mempercepat pertanyaan yang melibatkan kolom tersebut.

    Tentu saja, Anda dapat, misalnya, memasang INDEX satu kolom Friendship.AddresseeIdsendirian, multi kolom yang mencakup Friendship.RequesterIddan Friendship.AddresseeId, atau keduanya.

  • Hindari kompleksitas yang tidak perlu yang diperkenalkan oleh "mencari" nilai-nilai berbeda yang dikumpulkan bersama di dalam kolom yang sama (sangat mungkin diduplikasi, diketik dengan salah, dll.), Suatu tindakan yang pada akhirnya akan memperlambat fungsi sistem Anda, karena Anda akan harus menggunakan metode non-relasional yang menghabiskan sumber daya dan waktu untuk menyelesaikan tugas tersebut.

Jadi, ada beberapa alasan yang menyerukan untuk menganalisis lingkungan bisnis yang relevan dengan hati-hati untuk menandai tipe d dari setiap kolom tabel dengan akurasi.

Seperti yang dijelaskan, peran yang dimainkan oleh perancang basis data adalah yang terpenting untuk memanfaatkan sebaik-baiknya (1) manfaat tingkat logis yang ditawarkan oleh model relasional dan (2) mekanisme fisik yang disediakan oleh DBMS pilihan.


a , b , c , d Jelas, ketika bekerja dengan platform SQL (misalnya, Firebird dan PostgreSQL ) yang mendukung pembuatan DOMAIN (fitur relasional yang berbeda), Anda dapat mendeklarasikan kolom yang hanya menerima nilai yang menjadi milik masing-masing (dibatasi dengan tepat dan terkadang dibagikan) DOMAIN.


Satu atau lebih program aplikasi berbagi basis data yang sedang dipertimbangkan

Ketika Anda harus menggunakan arrayskode program aplikasi yang mengakses database, Anda hanya perlu mengambil set data yang relevan secara penuh dan kemudian "mengikatnya" ke struktur kode terkait atau menjalankan proses aplikasi terkait yang harus dilakukan.

Manfaat lebih lanjut dari kolom bernilai tunggal: Ekstensi struktur basis data jauh lebih mudah

Keuntungan lain dari memegang AddresseeIdtitik data dalam kolom yang diketik dan diketik dengan benar adalah bahwa itu sangat memudahkan memperluas struktur database, seperti yang akan saya contohkan di bawah ini.

Perkembangan skenario: Memasukkan konsep Status Persahabatan

Karena Persahabatan dapat berkembang dari waktu ke waktu Anda mungkin harus melacak fenomena seperti itu, sehingga Anda harus (i) memperluas skema konseptual dan (ii) mendeklarasikan beberapa tabel lagi dalam tata letak logis. Jadi, mari kita susun aturan bisnis selanjutnya untuk menggambarkan penggabungan baru:

  • Sebuah Persahabatan memegang satu-ke-banyak FriendshipStatuses
  • Sebuah FriendshipStatus terutama diidentifikasi oleh kombinasi yang RequesterId , yang AddresseeId dan yang SpecifiedDateTime
  • Seorang Pengguna menentukan nol-satu-atau-banyak FriendshipStatuses
  • Status A mengklasifikasikan nol-satu-atau-banyak FriendshipStatus
  • Sebuah Status terutama diidentifikasi oleh nya StatusCode
  • Sebuah Status bergantian diidentifikasi oleh nya Nama

Extended IDEF1X diagram

Secara berturut-turut, diagram IDEF1X sebelumnya dapat diperluas untuk memasukkan tipe entitas baru dan tipe interelasi yang dijelaskan di atas. Diagram yang menggambarkan elemen sebelumnya yang terkait dengan elemen baru disajikan pada Gambar 2 :

Gambar 2. Status Persahabatan IDEF1X Diagram

Penambahan struktur logis

Setelah itu, kita dapat memperpanjang tata letak DDL dengan deklarasi berikut:

--
CREATE TABLE MyStatus ( -- Denotes an independent entity type.
    StatusCode CHAR(1)  NOT NULL,
    Name       CHAR(30) NOT NULL,
    --
    CONSTRAINT MyStatus_PK PRIMARY KEY (StatusCode),
    CONSTRAINT MyStatus_AK UNIQUE      (Name) -- ALTERNATE KEY.
); 

CREATE TABLE FriendshipStatus ( -- Represents an associative entity type.
    RequesterId       INT      NOT NULL,
    AddresseeId       INT      NOT NULL,
    SpecifiedDateTime DATETIME NOT NULL,
    StatusCode        CHAR(1)  NOT NULL,
    SpecifierId       INT      NOT NULL,
    --
    CONSTRAINT FriendshipStatus_PK             PRIMARY KEY (RequesterId, AddresseeId, SpecifiedDateTime), -- Composite PRIMARY KEY.
    CONSTRAINT FriendshipStatusToFriendship_FK FOREIGN KEY (RequesterId, AddresseeId)
        REFERENCES Friendship  (RequesterId, AddresseeId), -- Composite FOREIGN KEY.
    CONSTRAINT FriendshipStatusToMyStatus_FK   FOREIGN KEY (StatusCode)
        REFERENCES MyStatus    (StatusCode),
    CONSTRAINT FriendshipStatusToSpecifier_FK  FOREIGN KEY (SpecifierId)
        REFERENCES UserProfile (UserId)      
);

Akibatnya, setiap kali Status Persahabatan yang diberikan harus diperbarui, Pengguna hanya perlu MENYIMPAN FriendshipStatusbaris baru , yang berisi:

  • yang cocok RequesterIddan AddresseeIdnilai-nilai -taken dari tentang Friendshipbaris-;

  • nilai baru dan bermakna - StatusCodediambil dari MyStatus.StatusCode-;

  • instan INSERTION yang tepat, yaitu, - lebih SpecifiedDateTimedisukai menggunakan fungsi server sehingga Anda dapat mengambil dan menyimpannya dengan cara yang andal—; dan

  • yang SpecifierIdnilai yang akan menunjukkan masing-masing UserIdyang masuk baru FriendshipStatuske dalam sistem -ideally, dengan bantuan aplikasi Anda (s) fasilitas-.

Sejauh itu, mari kita anggap bahwa MyStatustabel menyertakan data berikut — dengan nilai PK yang (a) pengguna akhir, programmer aplikasi, dan ramah-DBA dan (b) kecil dan cepat dalam hal byte di tingkat implementasi fisik -:

 + -—————————— + +—————————— +
 | StatusCode | Nama       |
 + -—————————— + +—————————— +
 | R | Diminta |
 + ------------ + ----------- +
 | A | Diterima |
 + ------------ + ----------- +
 | D | Ditolak |
 + ------------ + ----------- +
 | B | Diserbu |
 + ------------ + ----------- +

Jadi, FriendshipStatustabel dapat menyimpan data seperti yang ditunjukkan di bawah ini:

 + -——————————— + +———————————— + +———————————————————————— ———- + -—————————- +-—————————— +
 | RequesterId | AddresseeId | SpecifiedDateTime        | StatusCode | SpecifierId |
 + -——————————— + +———————————— + +———————————————————————— ———- + -—————————- +-—————————— +
 | 1750 | 1748 | 2016-04-01 16: 58: 12.000 | R | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-02 09: 12: 05.000 | A | 1748 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-04 10: 57: 01.000 | B | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-07 07: 33: 08.000 | R | 1748 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
 | 1750 | 1748 | 2016-04-08 12: 12: 09.000 | A | 1750 |
 + ------------- + ------------- + --------------------- ---- + ------------ + ------------- +

Seperti yang Anda lihat, dapat dikatakan bahwa FriendshipStatustabel melayani tujuan terdiri dari deret waktu .


Posting yang relevan

Anda mungkin juga tertarik pada:

  • Jawaban ini di mana saya menyarankan metode dasar untuk berurusan dengan banyak-ke-banyak hubungan umum antara dua jenis entitas yang berbeda.
  • Diagram IDEF1X ditunjukkan pada Gambar 1 yang menggambarkan jawaban lain ini . Bayar perhatian khusus pada jenis entitas bernama Pernikahan dan Progeni , karena mereka adalah dua contoh bagaimana untuk menangani “Bagian Ledakan Masalah”.
  • Posting ini yang menyajikan musyawarah singkat tentang memegang berbagai informasi dalam satu kolom.
MDCCL
sumber