作为主键的字符串?

问题描述:

我有这个数据库结构作为主键的字符串?

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

主键用于数据库。

显示名称是针对最终用户的。

不要混淆一个人!不要把一个主键从一个有意义的东西中取出来。迟早你会后悔的。

将代理键/标识/自动编号作为主键是一个非常好的主意,并且在数据库设计中被广泛使用。

您可以添加一列或甚至一个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

我相信应该那么简单。 但是,您需要确定要使用的字符串类型 http://dev.mysql.com/doc/refman/5.1/en/string-types.html

从你的问题中,我不清楚你对产品,类别和子类别做了什么来使你的零件编号。为了争辩的目的,我会假设你将它们连接在一起,如产品123,类别456,子类别789给出部件号123-456-789或其他一些。

我喜欢在实际中使用自然标识符作为主键。但“每当实际”可能是一个严重的限制。如果你天生的标识符是由某种方式结合其他三场,你有四种选择:

  1. 导致主键是这三个字段的组合。这往往是一种痛苦。所有加入必须匹配三个字段,搜索必须测试三个字段等。

  2. 创建一个新字段,将这三个字段连接起来,并将其用作priamry键。然后,只要其中一个“基本”字段发生更改,也要更改此连接字段。这是一个非常非常糟糕的主意。不要这样做。这是冗余数据,所有不良数据都来自冗余数据。

  3. 用一个组合字段替换三个单独的字段。这比#2更糟糕。现在,当你需要个人价值时,你必须把这个领域分开。

  4. 放弃并创建一个合成密钥,如序列号。将其用作主键,然后使用自然键进行显示。如果我的自然键需要连接或以其他方式操作三个字段,我倾向于使用此选项。

您的要求尚不清楚。你如何得到3个int列的“PS-5678”?在你的例子中只有2个组件。

你只需要将3个INT转换为一个CHAR()字符串?

如果是这样,数据库是好的,根本不需要改变表格!?!?!这三个组件已经可用,正确分离,作为不同的列。你正在寻找的仅仅是将三个组件显示为一个单独的字符串。