Mysql Выберите запись, где первичный ключ = х - PullRequest
3 голосов
/ 25 января 2011

У меня есть первичный ключ в моей таблице 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 ]

5 голосов
/ 25 января 2011

Я вижу две части вашего вопроса. Первая часть касается ссылки на составное значение. Я не уверен, поддерживает ли MySQL это, но это будет стандартный способ SQL сделать это:

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

Другая часть ссылается на столбцы первичного ключа, используя сокращенный синтаксис. Я не знаю такой возможности.

1 голос
/ 25 января 2011

Нет, такого способа нет ни в MySQL, ни в любом известном мне диалекте SQL.

Вы должны разбить строку 20001-1-2011-01-07 14:04:40 в своем PHP и использовать ее части для построения запроса MySQL.

Я мог бы также добавить, что составной первичный ключ может быть не самой лучшей идеей в плане производительности (особенно с таблицами InnoDB)

Кроме того, INT(5) по-прежнему занимает столько же места, сколько INT(11) (или просто INT в этом отношении).Для меньших целочисленных типов используйте TINYINT, SMALLINT и MEDIUMINT


Неуклюжий раздел Обходные пути

Решения ниже должны работать так, как вы хотите, ноза счет ресурсов и / или производительности.Если вы действительно не можете найти самое простое решение, вы не должны их использовать.


A ужасный способ сделать это будет выглядеть так WHERE CONCAT(OfficeCode,IssuerId,BulletinDtm) = '20001-1-2011-01-07 14:04:40'

Это УЖАСНО , потому что это не позволит MySQL использовать индекс для фактического ускорения запроса.

Не делайте этого, пожалуйста.


Другой способ.Добавьте столбец CHAR(32) в свою таблицу и сделайте его своим ПК.Сохраните в нем MD5-хэш ваших предыдущих столбцов PK (т. Е. MD5 ('20001-1-2011-01-07 14:04:40'). Затем вы можете запросить как: WHERE newPKcolumn = MD5('20001-1-2011-01-07 14:04:40'). Это позволит вам делать то, чтовы хотите, и MySQL будет использовать индекс. Таблица больше не нормализуется, но денормализация - это компромисс, который вам нужно иногда делать для повышения производительности или удобства использования. В этом нет ничего плохого.

0 голосов
/ 25 января 2011

Нет возможности сделать это так. Хранимая процедура предварительного анализа - один из способов сделать это. Если вам не нужно придерживаться этой схемы таблицы, я бы предложил заменить первичный ключ на новый столбец, который можно установить на автоинкремент.

Если вам нужно придерживаться этого дизайна, тогда вы все равно можете добавить новую таблицу «сопоставления», которая, как следует из названия, сопоставит вашу комбинацию с первичным ключом:

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 в строке запроса.

Приветствия

0 голосов
/ 25 января 2011

Вы можете создать хранимую процедуру, которая принимает '20001-1-2011-01-07 14:04:40' (строку) в качестве аргумента, затем проанализировать ее и сделать оператор SELECT внутри процедуры.

...