Apa cara paling efisien untuk menyimpan tag dalam database?

139

Saya menerapkan sistem pemberian tag di situs web saya yang mirip dengan satu stackoverflow, pertanyaan saya adalah - cara apa yang paling efektif untuk menyimpan tag sehingga dapat ditelusuri dan difilter?

Ide saya adalah ini:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Apakah ini terlalu lambat? Apakah ada cara yang lebih baik?

Logan Serman
sumber
2
Sebelumnya ditanyakan: stackoverflow.com/questions/20856/…
DrBloodmoney
2
Mulai 2016, gunakan Solr atau Elasticsearch
Charles L.

Jawaban:

193

Satu item akan memiliki banyak tag. Dan satu tanda akan menjadi milik banyak item. Ini menyiratkan kepada saya bahwa Anda sangat mungkin memerlukan tabel perantara untuk mengatasi kendala banyak-ke-banyak.

Sesuatu seperti:

Tabel: Item
Kolom: Item_ID, Item_Title, Konten

Tabel: Tag
Kolom: Tag_ID, Tag_Title

Tabel: Item_Tags
Kolom: Item_ID, Tag_ID

Mungkin aplikasi web Anda sangat populer dan perlu dinormalisasi di masa mendatang, tetapi tidak ada gunanya membuat air terlalu dini.

Simon Scarfe
sumber
jika ada yang namanya tagGroup cara menanganinya misal tag dikelompokkan ke dalam kategori misal: Bahasa pemrograman: c #, vb, pearl. OS: windows7, dos, linux dll
Thunder
4
@ Thunder: dengan asumsi bahwa satu tag mungkin hanya dimiliki oleh satu kategori, saya akan membuat tabel TagCategory yang terdiri dari category_id dan category_name. Dari sana, saya akan menambahkan bidang category_id ke tabel Tag dan menggabungkannya.
Simon Scarfe
8

Sebenarnya saya percaya de-normalisasi tabel tag mungkin cara yang lebih baik untuk maju, tergantung pada skalanya.

Dengan cara ini, tabel tag memiliki tagid, itemid, tagname.

Anda akan mendapatkan tagnames duplikat, tetapi menambahkan / menghapus / mengedit tag untuk item tertentu JAUH lebih sederhana. Anda tidak perlu membuat tag baru, menghapus alokasi yang lama dan mengalokasikan ulang yang baru, Anda cukup mengedit tagname.

Untuk menampilkan daftar tag, Anda cukup menggunakan DISTINCT atau GROUP BY, dan tentunya Anda dapat menghitung berapa kali tag digunakan dengan mudah juga.

Neil Barnwell
sumber
4

Jika Anda tidak keberatan menggunakan sedikit barang non-standar, Postgres versi 9.4 dan yang lebih baru memiliki opsi untuk menyimpan catatan jenis array teks JSON.

Skema Anda adalah:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Untuk info lebih lanjut, lihat posting luar biasa ini oleh Josh Berkus: http://www.databasesoup.com/2015/01/tag-all-things.html

Ada lebih banyak pilihan yang berbeda dibandingkan secara menyeluruh untuk kinerja dan yang disarankan di atas adalah yang terbaik secara keseluruhan.

Dmitry Shvedov
sumber
2

Anda tidak dapat benar-benar membicarakan kelambatan berdasarkan data yang Anda berikan dalam pertanyaan. Dan saya rasa Anda tidak perlu terlalu khawatir tentang kinerja pada tahap perkembangan ini. Ini disebut pengoptimalan prematur .

Namun, saya menyarankan agar Anda menyertakan kolom Tag_ID di tabel Tag. Biasanya merupakan praktik yang baik bahwa setiap tabel memiliki kolom ID.

Rockcoder
sumber
2

Saya akan menyarankan menggunakan tabel ketiga perantara untuk menyimpan tag <=> asosiasi item, karena kita memiliki hubungan banyak-ke-banyak antara tag dan item, yaitu satu item dapat dikaitkan dengan beberapa tag dan satu tag dapat dikaitkan dengan beberapa item. HTH, Katup.

Valentin Vasilyev
sumber
1

Jika ruang akan menjadi masalah, miliki Tag tabel ke-3 (Tag_Id, Judul) untuk menyimpan teks untuk tag dan kemudian ubah tabel Tag Anda menjadi (Tag_Id, Item_Id). Kedua nilai tersebut harus memberikan kunci utama komposit yang unik juga.

Adam Pope
sumber
0

Item harus memiliki kolom "ID", dan Tag harus memiliki kolom "ID" (Kunci Utama, Berkelompok).

Kemudian buat tabel perantara dari ItemID / TagID dan letakkan " Indeks Sempurna " di sana.

Timothy Khouri
sumber