【问题标题】:Many-to-one relationship using two unique keys使用两个唯一键的多对一关系
【发布时间】:2020-05-28 18:30:25
【问题描述】:

我有两个看起来像这样的表:

uploads
________
id (primary key)
user_id
file_checksum
upload_information
---------
upload_info_id (primary key)
file_checksum
metadata1
metdata2

我试图强制执行的“多对一”关系是这样的:

  • 许多上传文件可以具有相同的文件校验和
  • 但是,文件校验和只能指向一个upload_information 记录,因此file_checksumupload_info_id 之间的唯一约束在upload_information 表中是强制性的。

我想知道如何在 Postgres 中更改这些表以实现这种关系。

CREATE TABLE uploads (
  id SERIAL NOT NULL PRIMARY KEY,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  user_id VARCHAR NOT NULL,
  file_checksum VARCHAR NOT NULL,
);
CREATE TABLE upload_information (
  upload_info_id SERIAL NOT NULL PRIMARY KEY,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  file_checksum VARCHAR NOT NULL,
  file_name VARCHAR NOT NULL,
  source_file_url VARCHAR NOT NULL,
);

【问题讨论】:

  • 当两个用户上传相同的内容但文件名和来源网址不同时,您希望发生什么?
  • 唯一重要的是文件内容的MD5校验和,其他信息来自内部来源,不是用户编辑的。
  • MD5 is broken,即使是文件校验和。我可以建议转到SHA-2 吗?我还建议将校验和存储为bytea,而不是其十六进制字符串表示。效率更高。

标签: postgresql


【解决方案1】:

file_checksum 上添加unique index

create unique index unique_checksum on upload_information(file_checksum)

【讨论】:

  • 那我需要在uploadsfile_checksum上添加REFERENCES语句吗?
  • @codeadventurer 不,这不是参考。但是,使用该唯一索引,每个file_checksum 都只有一个upload_information。而不是存储uploads.file_checksum,您应该存储一个外键uploads.upload_information_id。这确实需要references。这使得uploadsupload_information 之间的关系变得明确。参照完整性现在可以工作了,您可以像 on delete 这样进行参照检查。
猜你喜欢
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
相关资源
最近更新 更多