兩者都不是很好的選擇。
選項1是一個不好的主意,因爲它使得通過電子郵件向用戶查找複雜而低效的任務。您需要在用戶記錄的電子郵件字段中執行全文搜索才能找到一封電子郵件。
選項2實際上是一個WORSE的想法,海事組織,因爲它使任何周圍的代碼寫一個巨大的痛苦。再次假設您需要查找所有具有值X的用戶。現在需要枚舉30列並檢查每列,以確定該值是否存在。痛苦!以這種方式
存儲數據 - 1或更多的數據的一些元件的 - 是在數據庫設計很常見的,並且如先前亞當提到,最好是在大多數情況下,通過使用歸一化的數據結構解決。
正確的表結構,寫在MySQL,因爲這被標記爲這樣的,可能是這樣的:
用戶表:
CREATE TABLE user (
user_id int auto_increment,
...
PRIMARY KEY (user_id)
);
電子郵件表:
CREATE TABLE user_email (
user_id int,
email char(60) not null default '',
FOREIGN KEY (user_id) REFERENCES user (user_id) ON DELETE CASCADE
);
的FOREIGN KEY
聲明是可選的 - 設計將在沒有它的情況下工作,但是,該行會導致數據庫強制關係。例如,如果您嘗試將記錄插入user_email
且user_id
爲10,則必須有對應的user
記錄,其中user_id
爲10,否則查詢將失敗。 ON DELETE CASCADE
告訴數據庫,如果您從user
表中刪除記錄,則與其關聯的所有user_email
記錄也將被刪除(您可能希望或不希望發生此行爲)。
這種設計當然也意味着當您檢索用戶記錄時需要執行聯接。像這樣的查詢:
SELECT user.user_id, user_email.email FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause>;
將返回一行存儲在系統中的每個user_email地址。如果您有5個用戶,每個用戶有5個電子郵件地址,則上述查詢將返回25行。
根據您的應用程序,您可能想要爲每個用戶獲得一行,但仍可以訪問所有電子郵件。在這種情況下,你可以嘗試聚合函數一樣GROUP_CONCAT
將每個用戶返回單行,請用逗號分隔的屬於該用戶的郵件列表:
SELECT user.user_id, GROUP_CONCAT(user_email.email) AS user_emails FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause> GROUP BY user.user_id;
同樣,根據您的應用程序,你可能希望向電子郵件列添加索引。
最後,在某些情況下,您不希望進行標準化的數據庫設計,並且帶有分隔文本的單列設計可能更合適,但這些情況很少。對於大多數正常的應用,這種標準化設計是一種方法,可以幫助它更好地執行和擴展。
我會強烈反對,第二個是一個很好的選擇,甚至可能不是比第一個更好的選擇。從應用程序設計的角度來看,甚至從性能的角度來看,爲一個值檢查30個不同的列是一場噩夢。 – futureal