儲存許多可能性的小數組
假設我需要將一系列書籍的文本逐行儲存在數據庫中,並將它們呈現在(基於 CMS)的網站中。我認為正確的設置是:
- 一個“圖書館”表:包含 ISBN 類型的資訊(每本書 ID:作者、標題、年份,可能是簡介)加上一個包含該書空白頁的數組。
- 每本書的“文本行”表。
這裡的“數組”問題與“儲存整數以進行有效選擇”和各種類似問題(如“將元素與星期幾匹配”)不同,因為(整數)選項的集合不受限制……它是稀疏的一個大而無界的範圍 AND 因為整個使用不在 SQL 中,而是在 PHP 中。
我現在有疑問:
$$ 1 $$我是否應該將所有書行表放在一個表中(添加包含書 ID 的列)?還是真的不重要?有清潔度/可讀性,有性能(一旦你選擇了“書”,你就不會切換——所以如果有很多,你會在一個較小的表中搜尋,這是我的想法)。$$ Further info: I have to add (and occasionally delete) books. I also need to assign an owner to each book (that can edit the ’lines’), but that is outside the scope of Mysql I think. $$ $$ 2 $$我應該如何保存每本書的“空頁”數組?–a 將 php 數組轉換為字元串(序列化/反序列化)並儲存為 varchar(或 tinytext)?或者 –b 製作另一張書籍表:空頁匹配?或者 –c 使用 SET(‘1’,‘2’,‘3’, …, ‘999’) 預見所有可能的空頁$$ and swear/blaspheme/explode violently the day I have to add a 1001-page-long book with an empty 1000th page $$? 或者 –d 從數據庫中即時計算? 我想“SET”方法可以防止不可能的數組,防止書籍的惡意“所有者”(在我的具體情況下這是相當不可能的);但是稀疏它的成本很大,並且很容易被超長的條目打破。我猜即時執行是不必要的慢,因為它是一個不變的列表(每個“書”計算一次,而不是每個“頁面”請求一次!)。我覺得解決方案 (a) 在這種情況下是最好的,因為我將它放在 PHP 中,這將用於創建整個結構和連結(在 HTML 中)。
MySQL SET 數據類型是一場災難——就像任何類型的數組數據類型一樣(不幸的是,許多 RDBMS 都支持)。在這裡查看我對另一個問題的回答。正如我所指出的,MySQLs SET 違反了 Codd 的第二條規則——沒有重複的組數據類型。如果您希望更改 RDBMS,它也是完全不可移植的。
如果您希望以這種方式儲存該數據,則有一個帶有 book_id、name、author、country_of_publication、subject….章節 book_id, chapter_id, page_id, pager_number, … 圖片… 其他內容… 然後是 LINE book_id, chapter_id, page_id, line_id, line_text…
這符合關係模型。我不清楚你為什麼要這樣做。TEXT 數據類型有什麼問題?此外,您可能想查看 FTS(全文搜尋) - MySQL 的本機 FTS(現在可在 MyISAM 和 InnoDB 上使用)。還有Lucene、Sphinx和Spider(很可能還有其他的 - Google 是你的朋友)。
$$ EDIT in response to OP’s comment $$
我覺得為每本書製作相同結構的表格是錯誤的
關鍵是你應該為所有書籍擁有相同結構的表格 - 你使結構足夠通用以應對(實際上)所有可能性。
但我也認為搜尋更大的表格(包含所有句子,而不僅僅是一本書的價值)來(重新)建構一個頁面,以及做一個額外的 WHERE book_id = ‘N’ 匹配會更慢……
在 book_id、chapter_id 甚至 page_id 上使用索引。此外,如果您要在整個語料庫中搜尋特定單詞,請考慮全文索引。
大概這個額外的成本與我首先將 mysql 發送到單書表幾乎相同。這給我留下了關於如何儲存一個小數組以在 PHP 中使用的查詢 — 我傾向於使用 (un)serialize 的 VARCHAR。
請注意,VARHCHAR 的最大大小為65535 字節- James Joyce 的某些句子可能超出此範圍:-),但即使 Joyce 也不太可能超出 TEXT 數據類型的 4GB :-)
我在 Google 上搜尋了“在 MySQL 中儲存書籍”並想出了這個您可能會感興趣的內容,並且有趣地在同一搜尋的第一頁上彈出了這個內容。