Jim*_*Jim 5 postgresql performance database-design optimization query-performance
我正在设计一个 PostgreSQL 数据库,该数据库将包含有关我的用户上传的照片的信息。所有用户都将拥有至少一张主照片和可选的一张或多张公开和/或私人照片。我的第一个架构如下:
user
----
id (PK)
photo
-----
id (PK)
user_id (FK to user)
photo_id (unique identifier such as "aK1q9")
type ("main" or "other")
access ("public" or "private")
Run Code Online (Sandbox Code Playgroud)
最常运行的查询是:
SELECT p.photo_id FROM photo p INNER JOIN user u ON p.user_id = u.id WHERE p.type = 'main' AND u.id = (some user id);
Run Code Online (Sandbox Code Playgroud)
下一个最受欢迎的查询将是:
SELECT p.photo_id FROM photo p INNER JOIN user u ON p.user_id = u.id WHERE p.type = 'other' AND p.access = 'public' AND u.id = (some user id);
Run Code Online (Sandbox Code Playgroud)
我预见的问题是 Photo 表会随着时间的推移变得非常大,因为它将包含所有用户上传的所有公共和私人照片。由于我最流行的查询只会查找主要照片 ID,将我的照片表分成三个表是否更有意义?
main_photo
----------
id (PK)
user_id (FK to user but in a one-to-one relationship to user)
photo_id
other_public_photo
------------------
id (PK)
user_id (FK to user)
photo_id
other_private_photo
-------------------
id (PK)
user_id (FK to user)
photo_id
Run Code Online (Sandbox Code Playgroud)
我认为后一种模式会更可取,因为 1) 每张照片的类型和访问信息都由它的存储位置明确表示,从而消除了我查询中的额外 AND;2) 我的查询会运行得更快,因为它们将针对三个较小的表之一而不是一个大表运行。从性能的角度来看,哪种方法是最佳方法?
谢谢。
小智 0
我认为,这是一个设计问题而不是数据库技术。因此,我提供了目前正在研究的数据库技术的答案。但是,您更喜欢使用伪代码来解释它,因此您可以使用另一个答案。我可以去编辑另一个,我故意保持原样,这样如果 SQL Server 人员访问此页面,他可能会感激,我们永远不知道!
表名称:用户
原因:要求始终将主照片与用户相关联,仅将主照片 ID 的引用与用户记录一起存储是有意义的。
Columns
----------------
UserId (PK)
PrimaryPhotoId (FK to Photo table)
Run Code Online (Sandbox Code Playgroud)
表名称:照片
描述:仅管理单个表会更容易。将来绝对可以扩展此表中的列,以防万一您想存储更多信息,如工具提示、替代文本、图像描述等。其他表不会受到干扰,并且绝对不需要更改。
Columns
----------------
PhotoId (PK)
Run Code Online (Sandbox Code Playgroud)
表名称:UserPhoto
描述:该表为您提供建立一对多关系的灵活性。它还使用标志(IsPrivate 列)来标识记录每张照片是私有的还是公开的。如果您希望限制每个用户不应将同一张照片关联两次,那么建议的复合唯一键就有意义,否则您需要扩展唯一键,但表设计应保持不变。
Columns
----------------
UserPhotoId (PK, AutoIncrement)
UserId (FK to User table) - Composite Unique Key
PhotoId (FK to Photo table) - Composite Unique Key
IsPrivate (Bit Data type to store 0 or 1. 0 value represents for 'Public', 1 value represents for 'Private' photo)
Run Code Online (Sandbox Code Playgroud)