Database-Design
書籤系統的數據庫設計
我正在創建一個書籤系統,人們可以在其中保存他們的書籤。每個使用者都有自己的帶有書籤的個人頁面。一個書籤應該至少有一個標籤,最多五個。每個使用者都可以創建無限的書籤/標籤。
我創建了以下表格:
User ---- Id Email Bookmark -------- Id UserId Title Url Tag --- Id UserId Title Description TagBookmark ----------- TagId BookmarkId
這是標準化的嗎?或者我應該這樣做嗎?這對一百萬個書籤會表現良好嗎?
我也不確定是否應該重複使用已經存在的書籤/標籤。
範例 1:
User1 和 User2 都創建了書籤“ http://google.com ”。我應該將此保存為一個書籤嗎?還是分別為每個使用者保存它們?
範例 2:
User1 和 User2 都創建標籤“搜尋引擎”。我應該將此保存為一個標籤嗎?還是分別為每個使用者保存它們?
如果我不在使用者之間重複使用書籤和標籤,這些表可能會變得非常大。
為預期的大型使用者群設計最佳性能,我建議確保書籤和標籤不會不必要地重複。使用下面我建議的架構,
http://google.com/
將成為單個書籤行。想要 Google 書籤的使用者在UserBookmarksTags
引用書籤行和關聯的標籤行時會有一行。我傾向於將 UserID 從 Bookmarks 表中抽像出來,並使用交叉引用表來確定哪些使用者有書籤,以及他們用什麼標記了每個書籤。
使用 SQL Server,我會這樣做:
USE tempdb; GO CREATE TABLE Users ( UserID INT NOT NULL CONSTRAINT PK_Users PRIMARY KEY CLUSTERED IDENTITY(1,1) , UserName varchar(255) ); CREATE TABLE Bookmarks ( BookmarkID INT NOT NULL CONSTRAINT PK_Bookmarks PRIMARY KEY CLUSTERED IDENTITY(1,1) , BookmarkName varchar(255) , BookmarkURL varchar(255) ); CREATE TABLE Tags ( TagID INT NOT NULL CONSTRAINT PK_Tags PRIMARY KEY CLUSTERED IDENTITY(1,1) , TagName varchar(255) );
如果系統中的每個條目都需要書籤和標籤,則可以使用下表來獲得最佳性能:
CREATE TABLE UsersBookmarksTags ( UserID INT NOT NULL CONSTRAINT FK_UsersBookmarksTags_UserID FOREIGN KEY REFERENCES Users(UserID) , TagID INT NOT NULL CONSTRAINT FK_UsersBookmarksTags_TagID FOREIGN KEY REFERENCES Tags(TagID) , BookmarkID INT NOT NULL CONSTRAINT FK_UsersBooksmarksTags_BookmarkID FOREIGN KEY REFERENCES Bookmarks(BookmarkID) , CONSTRAINT PK_UsersBookmarksTags PRIMARY KEY CLUSTERED (UserID, TagID, BookmarkID) );
上述版本的表格
UsersBookmarksTags
允許您快速返回與任何給定標籤匹配的特定使用者的書籤列表,或該使用者的所有書籤。或者,您可以創建允許標籤和書籤都為空條目的交叉引用表,如下所示:
CREATE TABLE UsersBookmarksTags ( UsersTagsBookmarksID INT NOT NULL CONSTRAINT PK_UsersBookmarksTags PRIMARY KEY CLUSTERED IDENTITY(1,1) , UserID INT NOT NULL CONSTRAINT FK_UserBookmarks_UserID FOREIGN KEY REFERENCES Users(UserID) , TagID INT NULL CONSTRAINT FK_UserBookmarks_TagID FOREIGN KEY REFERENCES Tags(TagID) , BookmarkID INT NULL CONSTRAINT FK_UserBooksmarks_BookmarkID FOREIGN KEY REFERENCES Bookmarks(BookmarkID) );
這允許具有沒有標籤的書籤的行,並且還允許將標籤與沒有書籤的使用者相關聯。
如果需要知道使用者添加的所有標籤,而這些標籤不一定具有關聯的書籤,我會考慮為此添加另一個表,如下所示:
CREATE TABLE UserTags ( UserID INT NOT NULL CONSTRAINT FK_UserTags_UserID FOREIGN KEY REFERENCES Users(UserID) , TagID INT NOT NULL CONSTRAINT FK_UserTags_TagID FOREIGN KEY REFERENCES Tags(TagID) , CONSTRAINT PK_UserTags PRIMARY KEY CLUSTERED (UserID, TagID) );