簡體   English   中英

將數據庫信息存儲為數組

[英]Storing database info as array

哪個是好的做法? 要將數據存儲為逗號分隔的列表或存儲在數據庫中?

我有一個表,用於說明帳戶,課程和注冊情況。 如果注冊表包含3個字段:ID,AccountID和ClassID,那么最好將ClassID用作包含逗號分隔列表(例如:“ 24,21,182,12”)的varchar,或者將其僅作為一個int並包含一個每個報名人數?

tldr: 不要這樣做 也就是說, 不要在此處使用“壓縮數組”

使用帶有“多行”的正確規范化設計。 這可能是多對多關系的良好候選人。 考慮以下結構:

Classes 1:M Enrollments(Class,Student) M:1 Students

遵循正確規范的設計將減輕痛苦。 此外,還有其他一些優點:

  • 參照完整性 (使用InnoDB)
    • 用關系描述一致的模型
    • 類型強制(不能有"foo,,"
  • 無需自定義代碼即可加入和查詢
    • “ A班學生的名字是什么?”
    • “誰要上一堂以上的課?”
    • 列可以用於索引(查詢性能)
    • 通常比本地處理代碼要快
  • 更加靈活一致
    • 可以將屬性附加到注冊中,例如狀態
    • 無需代碼即可在訪問站點上處理序列化
    • 容納更多的占位符和ORM

從來沒有通過將多個值與某種分隔符(例如逗號或固定長度的子字符串)組合在一起,將多個值填充到單個數據庫字段中。 在極少數情況下,這顯然可以帶來存儲要求或性能上的好處……請參閱規則1:永遠不要。 曾經

當您將多個值填充到單個字段中時,您會破壞數據庫引擎中內置的所有聰明功能,以幫助您檢索和操作值。

就像您說的那樣-我想這是某種學生數據庫。

Plan A

student (student_id, account_id, class_id_mash)

Plan B

student (student_id, account_id)
student_class (student_id, class_id)

好的,假設您要列出所有參加第27課的學生的清單。 使用計划B,您可以編寫

select student_id
from student join student_class on student.student_id=student_class.student_id
where class_id=27

簡單。

您將如何使用A計划? 你可能認為

select student_id
from student
where class_id_mash like '%27%'

但這不僅可以找到所有27年級的學生,而且還可以找到127年級或272年級的所有學生。

好的,如何:

select student_id
from student
where class_id_mash like '%,27,%'

在那里,現在我們找不到127或272! 但是,哎呀,如果27個碰巧是列表中的第一個或最后一個,我們也找不到它,因為那樣的話,雙方都沒有逗號。

好的,也許我們可以通過更多有關定界符的規則或更復雜的匹配表達式來解決此問題。 但這將是不必要的復雜和痛苦的。

即使我們做到了,每次對類ID的搜索都必須是一個完整的順序搜索。 每個字段只有一個值並且有多個記錄,您可以在class_id字段上創建索引,以快速高效地進行檢索。 (某些數據庫引擎可以索引到文本字段的中間,但是,又有一個簡單的解決方案,為什么還要進入復雜的解決方案呢?)

我們如何驗證class_id? 在單獨的字段中,我們可以說“ class_id引用類”,數據庫引擎將確保我們不會輸入非法值。 使用mash時,沒有這樣的免費驗證。

我都做到了,但是我沒有使用逗號分隔將信息存儲在數據庫中,而是使用了另一個定界符,例如| (這樣我就不必擔心在插入到db時進行格式化)。 它更多關於您查詢數據的頻率

如果只需要完整的列表,可以將其存儲為逗號分隔的值。 但是,如果您需要查詢列表,則應將它們分開存儲。

暫無
暫無

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

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