簡體   English   中英

索引鏈接表聰明嗎?

[英]Is indexing link tables smart?

舉例來說,我有2個表格:“用戶”>“項目”

用戶可以擁有收藏夾項目,並且一個項目可以有多個將其視為收藏夾的用戶,因此我將使用鏈接表。

現在我的鏈接表將包含以下內容:

id (int 11 AI)
user_id (int 11)
item_id (int 11)

現在將有必要/有用的是在user_id和item_id上放置索引,因為隨着時間的推移該表將包含很多記錄。

我不確定何時使用索引。 我的想法是何時使用它們(盡管可能完全不正確)是當您擁有大型數據庫並且需要在列上進行搜索/過濾然后為它建立索引時。 如果不正確,很抱歉,這就是我一直被告知的內容。

簡而言之,是的。

想象一下,如果每次您需要將主鍵值與另一個表中的外鍵進行匹配時,DBMS必須在整個表中搜索匹配的鍵,那么聯接將如何工作。

基本上,是的,就是這樣。

在這種情況下,我想說user_id列上的索引將很有用,因為您將向用戶顯示其收藏夾列表,對嗎?

item_id上的索引可能用處不大,因為我懷疑您將顯示喜歡某個特定項目的用戶列表。 盡管您可能會關心計數(“ 100個用戶喜歡此項目”),所以您可能最終會添加該索引。 或者,您可以取消規范化並將計數保留在items表中。 盡管您將需要編寫額外的代碼來維護該數字,但這將提供更好的性能。

最后但並非最不重要的-在鏈接表中,您可以id列。 只需在兩列上添加主鍵索引( item_id順序分別為user_iditem_id )。 這將確保您不能輸入重復的行,並且由於user_id是索引的第一列,因此您可以在搜索查詢中使用它。 不再需要僅在user_id列上添加單獨的索引。

但是,這也取決於您使用的代碼。 如果您使用某種需要為每個表分配id列的框架(ORM?),則此技巧無用。


根據要求由作者,這里有一個快速的介紹什么索引

假設您有一個數據庫表,它只是一排沒有特定順序的行。 假設我們有一個表格people ,其namesurnameage列。

現在,當您想查找John Smith的年齡時,您可能會進行如下查詢:

select age from people where name='John' and surname='Smith'

當您這樣做時,數據庫引擎只能做一件事-它必須遍歷所有行並尋找匹配的行。 如果有100,000行,那將會很慢。

現在有一種更快的方法。 考慮一下電話簿(經典紙質版)。 在數千頁的黃頁上,有數百人的電話號碼。 但是,即使您是人類,也可以很快找到所需的號碼。 這是因為數字是按名稱和姓氏的字母順序排序的。 您打開一個隨機頁面,您可以立即看到您要查找的數字是在打開頁面之前還是之后。 重復幾次,您已經找到了。

這種搜索稱為“二進制搜索”。 如果記錄按名稱和姓氏排序,那么數據庫引擎也可以執行此操作。 因此,這就是主鍵-它告訴數據庫不是按某種隨機順序存儲記錄,而是按某些列排序。 當出現新記錄時,它可以快速找到其應有的位置並將其推入該位置,從而使該表永遠保持排序狀態。

這里已經有幾件事要注意。

首先,您可以按一個或多個列進行排序,但是,就像在電話簿中一樣,順序很重要。 如果您先按name排序,然后按surname排序,那么這就是記錄的順序。因此,您將能夠快速找到name='John'name='John' and surname='Smith' ,但是如果您只需要找到surname='Smith' ,那對您完全沒有幫助。 就像在電話簿中一樣。

其次,將記錄推到中間的位置也有些慢。 並非犯罪,但仍然如此。 在末尾附加記錄更快。 因此,人們傾向於將auto_increment列用作其主鍵,因為這樣,每個新行都將放在末尾。

第三,在大多數數據庫中,主鍵不僅用於快速搜索,而且還唯一地標識行。 這意味着如果有兩行的主鍵列值相等,則數據庫將不滿意。 在那種情況下,它無法確定哪個必須先走,哪個必須最后走,而且它也不是唯一的。 使用auto_increment另一個原因。 請注意,如果PK索引中有多個列,則它們的組合必須是唯一的-每個列單獨可能是不唯一的。 在我們的情況下,這意味着可以有許多約翰和許多​​史密斯,但只有一個約翰·史密斯。

但是我們仍然有一個問題。 如果我們想快速查找僅包含namesurname行,該怎么辦? PK索引只能做這些事情之一,不能同時做。

這是其他非PK索引發揮作用的地方。 您可以將任意數量的表添加到表中。 在我們的例子中,我們可以創建另一個索引來僅保留surname列。

當我們這樣做時,數據庫會創建另一個隱藏表(好的,不是這樣,但您可以這樣想),它是原始表的副本,但只有surname列和返回到其中的行的特殊鏈接原始表。 該隱藏索引表按surname列排序。 因此,當您現在只需要指定surname來查找行時,數據庫引擎可以在隱藏的索引表中查找該行,然后將其鏈接回到原始行並從原始行中獲取數據。 快多了。

這些非PK指數通常也有幾種味道。 有一個標准的“索引”根本沒有任何限制-您可以在列,空值等中有重復的值。有一個“唯一的”索引,它強制索引中的所有值都必須是唯一的。 然后有時會有一些特殊的索引,例如FullText,Spatial等。索引也傾向於具有一些技術選擇,但是您必須閱讀這些的數據庫文檔。

最后要注意的一件事是-索引可以快速地在表中查找內容,但是它們要付出一定的代價。 對表的修改(插入,更新,刪除)變慢,因為索引也需要更新。 請記住這一點,僅在必要時添加它們。

除主鍵外。 始終添加主鍵。 那是命令! :)

暫無
暫無

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

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