簡體   English   中英

我應該為我的sqlalchemy模型使用代理鍵(id = 1)還是自然主鍵(tag ='sqlalchemy')?

[英]Should I use a surrogate key (id= 1) or natural primary key (tag='sqlalchemy') for my sqlalchemy model?

在數據庫方面,我認為自然主鍵是可取的,只要它不會過長,這可能會導致索引性能問題。 但是當我正在閱讀通過谷歌代碼搜索使用sqlalchemy的項目時,我幾乎總能找到類似的東西:

class MyClass(Base):
    __tablename__ = 'myclass'
    id = Column(Integer, primary_key=True)

如果我有一個簡單的類,比如標簽,我只計划存儲一個值並且需要唯一性,當我使用sqlalchemy時,通過代理主鍵可以獲得什么? 我正在閱讀的一本SQL書籍暗示ORM是“反模式”的合法用途,但他設想的ORM聽起來更像是ActiveRecord或Django。 這出現在我的模型中的一些地方,但這里是一個:

class Tag(Base):
    __tablename__ = 'tag'
    id = Column(Integer, primary_key=True) #should I drop this and add primary_key to Tag.tag?
    tag = Column(Unicode(25), unique=True) 
    ....

在我更廣泛的關系模型中,Tag與其他對象具有多個多對多關系。 因此,將有許多中間表必須存儲更長的密鑰。 我應該為我的主鍵選擇標簽或ID嗎?

雖然ORM或編程語言比其他語言更容易使用,但我認為選擇主鍵是與ORM無關的數據庫設計問題。 以自己的理由獲得數據庫架構更為重要。 無論如何,數據庫往往比訪問它們的代碼更長壽。

搜索SO(和谷歌)以獲取有關如何選擇主鍵的更多一般性問題,例如: https//stackoverflow.com/search q = primary + key + natural+surrogate+database-design代理與自然/商業密鑰關系數據庫設計問題 - 代理鍵還是自然鍵?何時不使用代理主鍵? ,...)


我假設Tag表不會很大或非常動態。 在這種情況下, 會嘗試使用tag作為主鍵,除非有重要的理由為最終用戶主鍵添加一些不可見的 ,例如:

  • 在現實世界數據下表現不佳(測量,未想象),

  • 頻繁更改標簽名稱(但是,我仍然會使用一些基於首次使用的標簽名稱作為密鑰的唯一字符串),

  • 不可見的幕后合並標簽(但是,見前一點),

  • 不同排序規則的問題 - 比較國際數據 - 在您的RDBMS中(但是......)

  • ...


總的來說,我觀察到人們往往在兩個方向都犯錯誤:

  • 通過使用復雜的多字段“自然”鍵(特定字段本身是不透明的數字),當表行具有自己的標識並且可以從擁有自己的代理ID中受益時,

  • 通過為所有內容引入隨機數字代碼,而不是使用短有意義的字符串。

有意義的主鍵值 - 如果可能 - 在手動瀏覽數據庫時證明自己很有用。 您不需要多個連接來計算數據。

我個人更喜歡大多數地方的代理鍵; 造成這種情況的兩個最大原因是1)整數鍵通常更小/更快; 2)更新數據不需要級聯。 對於你正在做的事情,第二點是相當重要的一點; 如果有多個表引用標記表,那么請記住,如果有人想要更新標記(例如,修復拼寫/案例錯誤,或使用更多/更少特定的單詞等),更新將需要同時在所有表格中完成。

我不是說你永遠不應該使用自然鍵 - 如果我確定自然鍵永遠不會改變,我會考慮一個自然鍵。 只是要確定,否則它會變得很難維持。

每當我看到人們(使用代理鍵)時,我都記得Roy Hann關於這個主題的博客文章,尤其是第二篇和第三篇文章:

我強烈建議人們閱讀這些文章,因為這些文章來自一個花了幾十年作為數據庫專家的人。

如今,替代密鑰的使用讓我想起了21世紀的早期,當時人們使用XML進行字面上的所有事情,包括它確實屬於什么,以及它不屬於哪里。

暫無
暫無

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

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