2010-11-03 96 views
2

我有這個數據庫結構作爲主鍵的字符串?

CREATE TABLE `productinfo` (
    `ProductID` int(11) NOT NULL AUTO_INCREMENT, 
    `ProductName` varchar(255) NOT NULL, 
    `ProductImage` varchar(255) NOT NULL, 
    `CategoryID` int(11) NOT NULL, 
    `SubCategoryID` int(11) NOT NULL, 
    `ProductBrief` varchar(255) NOT NULL, 
    `Features` text NOT NULL, 
    `Specifications` text NOT NULL, 
    `Reviews` text NOT NULL, 
    `Price` varchar(255) NOT NULL, 
    `Status` tinyint(4) NOT NULL, 
    PRIMARY KEY (`ProductID`) 
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; 

我現在我需要把產品ID,類別ID,並SubCategoryID到像PS-5678一個字符串的部件號。 ProductID是主鍵,所以如何更改數據庫的結構。類別ID,並SubCategoryID在其他表的主鍵,以便如何處理this..is它那麼容易,因爲轉彎

`ProductID` int(11) NOT NULL AUTO_INCREMENT 

成string..and擺脫

PRIMARY KEY (`ProductID`) 

的意見,建議任何人

+1

特別是如果您需要處理ORM,只需保留現有的PK並在「漂亮的字符串產品ID」上使用唯一的覆蓋索引就更容易了(實際上這聽起來有點類似於SubCat的非規範化,等等......) – 2010-11-03 23:15:09

回答

8

主鍵用於數據庫。

顯示名稱是針對最終用戶的。

不要混淆一個人!不要把一個主鍵從一個有意義的東西中取出來。遲早你會後悔的。

將代理鍵/標識/自動編號作爲主鍵是一個非常好的主意,並且在數據庫設計中被廣泛使用。

您可以添加一列或甚至一個DERIVED COLUMN並在其上添加唯一約束。

+0

你能給我一個代理鍵/身份/自動編號作爲主鍵的例子嗎? – Trace 2010-11-03 23:17:02

+0

@Matt:你不需要一個例子 - 這正是你第一次做的!忘記您將ProductId轉換爲varchar列的意圖......實際上,由於此「新字段」僅僅是一個計算表達式,您甚至不需要使用此值創建列。在顯示之前只需連接基礎字段。 – rsenna 2010-11-03 23:20:15

+1

-1在代理鍵上創建派生列破壞了具有代理項的值。您應該在有意義的業務密鑰上強制執行唯一性約束,而不依賴於您使用的任何代理鍵。你是否也需要代孕是一個單獨的決定。 – sqlvogel 2010-11-04 07:43:24

0

從你的問題中,我不清楚你對產品,類別和子類別做了什麼來使你的零件編號。爲了爭辯的目的,我會假設你將它們連接在一起,如產品123,類別456,子類別789給出部件號123-456-789或其他一些。

我喜歡在實際中使用自然標識符作爲主鍵。但「每當實際」可能是一個嚴重的限制。如果你天生的標識符是由某種方式結合其他三場,你有四種選擇:

  1. 導致主鍵是這三個字段的組合。這往往是一種痛苦。所有加入必須匹配三個字段,搜索必須測試三個字段等。

  2. 創建一個新字段,將這三個字段連接起來,並將其用作priamry鍵。然後,只要其中一個「基本」字段發生更改,也要更改此連接字段。這是一個非常非常糟糕的主意。不要這樣做。這是冗餘數據,所有不良數據都來自冗餘數據。

  3. 用一個組合字段替換三個單獨的字段。這比#2更糟糕。現在,當你需要個人價值時,你必須把這個領域分開。

  4. 放棄並創建一個合成密鑰,如序列號。將其用作主鍵,然後使用自然鍵進行顯示。如果我的自然鍵需要連接或以其他方式操作三個字段,我傾向於使用此選項。

1

您的要求尚不清楚。你如何得到3個int列的「PS-5678」?在你的例子中只有2個組件。

你只需要將3個INT轉換爲一個CHAR()字符串?

如果是這樣,數據庫是好的,根本不需要改變表格!?!?!這三個組件已經可用,正確分離,作爲不同的列。你正在尋找的僅僅是將三個組件顯示爲一個單獨的字符串。