簡體   English   中英

數據庫最佳實踐

[英]Database best practices

我有一個存儲注釋的表,注釋可以來自另一個用戶,或者是另一個在此應用中是獨立實體的配置文件。

我原來的想法是該表將同時具有user_id和profile_id字段,因此如果用戶提交注釋,則會給user_id留下profile_id為空

這是對的,錯的,還有更好的方法嗎?

無論最好的解決方案是什么,都取決於恕我直言,而不僅僅是表格,還取決於如何在應用程序的其他地方使用它。

假設注釋都與其他對象相關聯,假設您從該對象中提取所有注釋。 在您提出的設計中,提取所有注釋需要從一個表中進行選擇,這是有效的。 但這是在不提取每條評論的海報信息的情況下提取評論。 也許你不想展示它,或者它們已經被緩存在內存中了。

但是,如果您在檢索評論時必須檢索有關海報的信息呢? 然后你必須加入兩個不同的表,現在結果記錄集被污染了很多NULL值(對於配置文件注釋,所有用戶字段都將為NULL)。 必須解析此結果集的代碼也可能變得更復雜。

就個人而言,我可能會從完全規范化的版本開始,然后在我開始看到性能問題時進行非規范化

對於該問題,還有一種完全不同的可能解決方案,但這取決於它是否在域中有意義。 如果應用程序中有其他位置可以互換使用用戶和海報,該怎么辦? 如果用戶只是一種特殊的個人資料怎么辦? 然后我認為解決方案通常應該在用戶/配置文件表中解決。 例如(一些縮寫的偽sql):

create table AbstractProfile (ID primary key, type ) -- type can be 'user' or 'profile'
create table User(ProfileID primary key references AbstractProfile , ...)
create table Profile(ProfileID primary key references AbstractProfile , ...)

然后,您的應用程序中可以互換使用用戶或配置文件的任何位置,您可以引用LoginID。

如果注釋對於多個對象是通用的,則可以為每個對象創建一個表:

user_comments (user_id, comment_id)
profile_comments (profile_id, comment_id)

然后,您的注釋表中不必包含任何空列。 它還可以在將來輕松添加新的comment-source-objects而無需觸及comments表。

另一種解決方法是始終對注釋中的評論者名稱進行非規范化(復制),並通過類型和id字段將引用存儲回評論者。 這樣你就可以在一個統一的評論表中快速搜索,排序和修剪。 缺點是評論和它的所有者之間沒有任何真正的FK關系。

在過去,我使用了一個集中的注釋表,並為它引用的fk_table提供了一個字段。

例如:

comments(id,fk_id,fk_table,comment_text)

這樣,您可以使用UNION查詢來連接來自多個源的數據。

SELECT c.comment_text FROM comment c JOIN user u ON u.id=c.fk_id WHERE c.fk_table="user"
UNION ALL
SELECT c.comment_text FROM comment c JOIN profile p ON p.id=c.fk_id WHERE c.fk_table="profile"

這可確保您可以擴展具有注釋的對象數,而無需創建冗余表。

這是另一種方法,它允許您通過外鍵維護參照完整性,集中管理,並使用標准數據庫工具(如索引)提供最高性能,如果您確實需要,還可以進行分區等:

create table actor_master_table(
  type char(1) not null, /* e.g. 'u' or 'p' for user / profile */
  id varchar(20) not null, /* e.g. 'someuser' or 'someprofile' */
  primary key(type, id)
);

create table user(
  type char(1) not null,
  id varchar(20) not null,
  ...
  check (id = 'u'),
  foreign key (type, id) references actor_master_table(type, id)
);

create table profile(
  type char(1) not null,
  id varchar(20) not null,
  ...
  check (id = 'p'),
  foreign key (type, id) references actor_master_table(type, id)
);

create table comment(
  creator_type char(1) not null,
  creator_id varchar(20) not null,
  comment text not null,
  foreign key(creator_type, creator_id) references actor_master_table(type, id)
);

暫無
暫無

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

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