Database-Design

書籤系統的數據庫設計

  • December 11, 2013

我正在創建一個書籤系統,人們可以在其中保存他們的書籤。每個使用者都有自己的帶有書籤的個人頁面。一個書籤應該至少有一個標籤,最多五個。每個使用者都可以創建無限的書籤/標籤。

我創建了以下表格:

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)
);

引用自:https://dba.stackexchange.com/questions/54851