【问题标题】:Good or bad database design好的或坏的数据库设计
【发布时间】:2016-12-06 23:21:13
【问题描述】:

我有以下迁移:

create table(:countries_codes) do

  add :iso, :string, size: 2
  add :name, :string

  timestamps
end
create unique_index(:countries_codes, [:iso])

create table(:languages_codes) do

  add :iso, :string, size: 2
  add :name, :string

  timestamps

end
create unique_index(:languages_codes, [:iso])

create table(:countries) do

  add :country_iso_id,  references(:countries_codes)
  add :language_iso_id, references(:languages_codes)
  add :name, :string

  timestamps
end
create unique_index(:countries, [:country_iso_id, :language_iso_id])

countries_codeslanguages_codes 上的iso 字段作为主键,禁用自动生成的id 字段会更好吗?

create table(:languages_codes, primary_key: false) do

  add :iso, :string, size: 2, primary_key: true
  add :name, :string

  timestamps

end

create table(:countries, primary_key: false) do

  add :country_iso,  references(:countries_codes, column: :iso, type: :string), primary_key: true
  add :language_iso, references(:languages_codes, column: :iso, type: :string), primary_key: true
  add :name, :string

  timestamps
end

create table(:countries_codes, primary_key: false) do

  add :iso, :string, size: 2, primary_key: true
  add :name, :string

  timestamps
end

【问题讨论】:

  • 我认为“更好”在这里是一个相对术语,不同的人会根据自己的需要做不同的事情。正因为如此,我投票结束这个,因为我认为答案将基于意见。
  • 尝试查看有关代理键 (en.wikipedia.org/wiki/Surrogate_key) 的*文章,了解这两种方法的一些优缺点。

标签: postgresql elixir ecto


【解决方案1】:

“更好”是主观的,但是当已经有一个自然唯一且相当短的值时,自动生成的 ID 没有意义。将代码设为主键,避免自动生成 ID。

【讨论】:

  • 我遇到了一些不同意你的数据库专家。谷歌“代理键”看看我的意思。尤其是这个(来自*的文章):Having the key independent of all other columns insulates the database relationships from changes in data values or database design (making the database more agile) and guarantees uniqueness.
  • 我同意你的看法。我们现在假设的唯一性可能以后不再唯一,并且代理键有助于避免在必须进行更改时对系统进行级联更改。我只是更喜欢仅在需要时增加复杂性,并确保在初始假设不成立时轻松更改系统的其余部分。但我倾向于在所有代码都在我们控制之下的地方进行操作,并且我们可以部署所有受影响的代码。
  • 这是一个公平的观察丹。我们中的太多人把“以防万一”的复杂性和过早地过度复杂化的问题放在一起。