5

我的 mysql 表中有一个主键,它由三列组成。

CREATE TABLE IF NOT EXISTS `bb_bulletin` (
  `OfficeCode` int(5) NOT NULL,
  `IssuerId` int(11) NOT NULL,
  `BulletinDtm` datetime NOT NULL,
  `CategoryCode` varchar(4) NOT NULL,
  `Title` varchar(255) NOT NULL,
  `Content` text NOT NULL,
  PRIMARY KEY (`OfficeCode`,`IssuerId`,`BulletinDtm`),
  UNIQUE KEY `U_IssuerId` (`IssuerId`,`OfficeCode`,`BulletinDtm`),
  UNIQUE KEY `U_CategoryCode` (`CategoryCode`,`OfficeCode`,`IssuerId`,`BulletinDtm`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

是否有一种速记方法来选择主键的给定值的记录。

我试过了。

SELECT * FROM `bb_bulletin` WHERE PRIMARY = '20001-1-2011-01-07 14:04:40'

而不是长手的做法,

SELECT * From bb_bulletin WHERE OfficeCode = 20001 AND IssuerId = 1 AND BulletinDtm = 2011-01-07 14:04:40

处理表中的 php 和复合键时的标准是什么。注意:我不想在我的表中添加自动递增键来解决这个问题。如果不可能,那么我将在我的 url 中传递三个约束。

4

4 回答 4

8

我看到你的问题有两个部分。第一部分是关于引用复合值。我不确定 MySQL 是否支持这一点,但这将是 SQL 标准的执行方式:

SELECT * FROM bb_bulletin WHERE (OfficeCode, IssuerId, BulletinDtm) = (20001, 1, '2011-01-07 14:04:40');

另一部分是使用缩写语法引用主键列。我不知道有这种可能性。

于 2011-01-25T00:10:20.663 回答
1

不,在 MySQL 或我知道的任何 SQL 方言中都没有这种方法。

您应该在 PHP 中拆分20001-1-2011-01-07 14:04:40字符串并使用它的部分来构建您的 MySQL 查询。

我还可以补充一点,复合主键在性能方面可能不是最好的主意(尤其是对于 InnoDB 表)

也仍然需要与(或就此而言)INT(5)一样多的空间。对于较小的整数类型,使用,和INT(11)INTTINYINTSMALLINTMEDIUMINT


笨拙的解决方法部分

下面的解决方案应该按照您想要的方式工作,但会以资源和/或性能为代价。除非你真的不能使用最简单的解决方案,否则你不应该使用这些。


一个可怕的方法是这样的 WHERE CONCAT(OfficeCode,IssuerId,BulletinDtm) = '20001-1-2011-01-07 14:04:40'

这是可怕的,因为它不允许 MySQL 使用索引来实际加速查询。

请不要这样做。


另一种方式。在您的表格中添加一CHAR(32)列并将其作为您的 PK。在其中存储您以前的 PK 列的 MD5 哈希(即 MD5('20001-1-2011-01-07 14:04:40')。然后您可以查询:WHERE newPKcolumn = MD5('20001-1-2011-01-07 14:04:40'). 这将允许您做您想做的事,和 MySQL 使用索引。该表不再规范化,但非规范化是您有时需要做的权衡,以提高性能或可用性。这没有错。

于 2011-01-24T23:40:43.903 回答
0

'20001-1-2011-01-07 14:04:40'您可以创建一个将(字符串)作为参数的存储过程,然后解析它并SELECT在过程中创建语句。

于 2011-01-24T23:43:05.570 回答
0

不可能那样做。预解析的存储过程是完成此任务的一种方法。如果您不必坚持使用此表设计,我建议将主键更改为可以设置为自动增量的新列。

如果您必须坚持这种设计,那么您仍然可以添加一个新的“映射”表,顾名思义,它将您的组合映射到主键:

CREATE TABLE IF NOT EXISTS `bbb_mapping` (
  `YourPK` int(11) NOT NULL AUTO_INCREMENT,
  `OfficeCode` int(5) NOT NULL,
  `IssuerId` int(11) NOT NULL,
  `BulletinDtm` datetime NOT NULL
  PRIMARY KEY (`YourPK`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

使用这种方法,您可以在查询字符串中使用 YourPK 时将映射表与原始表连接起来。

干杯

于 2011-01-24T23:56:14.467 回答