簡體   English   中英

Mysql 在表中存儲任意數量的值的最佳方式

[英]Mysql Best way to store an arbitrary number of value in a table

我想知道什么是最好的存儲方法,讓我們說user表中的languages ,當用戶可以擁有他想要的盡可能多的語言時,並且希望不使用序列化數據,因為這個字段將被密集搜索。

我在想限制條目的數量,例如最大 4 種語言,並且在用戶表中有 lang1、lang2..

有沒有更好的方法來實現這一目標?

這稱為數據庫規范化 具體來說,你需要 map 一個“多對多”關聯

你需要 3 張桌子。

User(id, name)
Language (id, language_name)
User_Language(id,id_user,id_language)

獲取用戶 id 3 的所有語言:

SELECT l.language_name
FROM User u
JOIN user_language ul ON (u.id=ul.id_user)
JOIN  Language l ON (l.id = ul.id_language)
WHERE u.id = 3

編輯:

注意@silkAdmin 有兩點很重要。 第一個,正如@BryceAtNetwork23 指出的那樣,不需要在 User_Language 表上放置一個 id。 第二個是,您應該了解連接,特別是 MySQL 連接(因為 SQL 在不同的數據庫引擎中往往不同)。 在你深入挖掘之后,你將能夠看到在之前的查詢中也不需要加入 User 表,這可以簡化為:

SELECT l.language_name
FROM user_language ul
JOIN  Language l ON (l.id = ul.id_language)
WHERE ul.user_id = 3

但是我在第一個答案中添加了它,以使事情對您來說更容易。

為什么使用語言表

我的回答只是反映了我會這樣做的方式。 有很多方法可以完成所要求的。 這么說,我自己解釋。

讓我們極端地想一想。 第一個極端是將語言存儲在用戶表中,正如您上面所說的。 例如,我們可以有一列並用分號分隔值。 像這樣的東西

User: (1, "John", "spanish;english;japanese")

這樣做的好處是您不需要任何連接。 鑒於您的用戶的 ID,您可以獲得語言。 缺點是搜索起來真的很痛苦。 您如何讓所有用戶使用“西班牙語”語言? (這里的底線是你不能索引你的數據)。 另一個缺點,現在有點老了,是磁盤空間的過度使用。 在發明 DB 和 Normalization 的時候,磁盤空間非常昂貴。 所以,存儲這個:

User: (1, "John", "spanish;english;japanese") 
User: (2, "Mary", "spanish;english")

那是不能容忍的事情。 所以,有人過來說:“嘿,讓我們使用 id,這樣我們就可以把它變成”:

User: (1, "John", "1;2;3") 
User: (2, "Mary", "1;2")

Language (1,"spanish")
Language (2,"english")

對於 10.000 名用戶和幾百種語言,這是磁盤使用量的巨大改進(也許在我們這個時代,這不再是真的,我稍后會談到)。 這解決了磁盤問題,但我們仍然有搜索問題。 同樣,您如何讓所有用戶使用“西班牙語”語言? 那么,對於這種設計,您應該遍歷用戶表並獲取語言列,將其拆分為“;” 並尋找 id 1。

這就是我們開始使用我之前向您展示的方法的原因。

所以,到目前為止一切順利。 很好的解釋;)

大免責聲明

正如我之前所說,有幾種方法可以做到這一點。 這取決於您的情況以及您想要實現的目標。 如果您想根據該列進行搜索(例如,給我說英語的用戶),您應該考慮我在答案頂部告訴您的設計。

現在有一個“新浪潮”的數據解決方案被稱為 no-sql 數據庫(它有所不同),它們試圖對數據進行非規范化。 如果您擔心模式的過度規范化,您應該看看它。 我向您推薦 MongoDB 和 CouchDB,因為它們更容易上手。

關於加入

不用擔心 2 連接的性能。 如果你有性能問題,那不是為了這個。 數據庫引擎就是為此目的而創建的。 通過良好的 memory 緩存和索引優化,它應該可以順利運行。

是的,最好的方法是使用一個包含lang_iduser_id列的附加表。 您可以在那里存儲任意數量的用戶/語言關聯(每行一個)。

創建表 user_languages

 user_id int,
 language_id int,

有約束:

 PRIMARY KEY (user_id, language_id),
 FOREIGN KEY (language_id) REFERENCES language(id),
 FOREIGN KEY (user_id) REFERENCES users(id)

有了這樣的限制,用戶可以根據需要分配任意多種語言。

我認為實現此目的的最佳方法是擁有一個 USER 表、一個 USER_LANGUAGES 表和一個 LANGUAGES 表。 這樣,用戶可以擁有任意多的語言。

USER
user_id int
user_name varchar

USER_LANGUAGES
user_id int
lang_id int

LANGUAGES
lang_id int
lang_name varchar

USER 存儲基於用戶的字段。 LANGUAGES 存儲每種特定語言(英語、德語等)的數據。 USER_LANGUAGES 存儲哪些用戶知道哪些語言的關聯。

我認為你應該考慮有兩張桌子。 一個是users ,一個是languages 它更容易維護,也更容易joins這些表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM