2011-01-24 4 views
3

У меня есть первичный ключ в моей таблице mysql, который состоит из трех столбцов.Mysql Выберите запись, где PRIMARY key = x

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

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

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

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

+1

MySQL поддерживает такой синтаксис (по крайней мере, в 5.2) – Mchl

+0

Я просто составлял синтаксис того, как я думал, что это будет сделано, но то, что вы предоставили выше, выглядит как хороший сокращенный метод, если он работает. Слава богу, давай. – andrew

+0

Есть ли название для того, что вы здесь сделали? Т.е. указывая столбцы как список, разделенный запятыми, а затем значения как список, разделенный запятой? – andrew

1

Нет, такого метода нет ни в MySQL, ни на любом SQL-диалекте, который я знаю.

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

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

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


Неуклюжих Обходного раздел

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


ужасный способ сделать это было бы, как этот 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

Хм, он делает составные клавиши немного болью в заднице, насколько это касается приложения, потому что, когда вы хотите настроить таргетинг на определенный элемент, вам нужно иметь такую ​​ссылку. index.php? action = someaction & OfficeCode = x & issuerId = y & BulletinDtm = z – andrew

+0

Нельзя сказать больше, кроме «нет, не совсем». Я скажу, что не могу придумать какой-либо веской причины, почему кто-то захочет это сделать, либо 8- | ТАКЖЕ: лично я придерживаюсь первичных ключей автоинкремента с одним столбцом все время, для простоты (используя уникальные ключи для других значений, поскольку op уже делает) – TehShrike

+0

Или вам нужно иметь фрагмент кода, который будет разделять значение PK, заданных в URL-адресе, в составные части. – Mchl

0

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

+0

Я никогда раньше ничего подобного не делал. Можете ли вы описать процедуру немного больше, чтобы я мог это исследовать? – andrew

+1

Вы могли бы это сделать, но это было бы слишком сложно и добавить ненужную неэффективность. То, что вы пытаетесь сделать, это не очень хорошая идея, andrew. Если вы хотите передать одну строку, разберите эту строку в своем коде перед тем, как вы создадите запрос. – TehShrike

+0

Если нет способа сделать сокращенный выбор с использованием первичного ключа, тогда я просто передам все три аргумента в URL-адресе. – andrew

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 в querystring.

Cheers

+0

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

+0

Это именно та идея: D. Из вашего имени таблицы я предполагаю, что вы пытаетесь взломать доску объявлений PHPBB. Добавление автоинкремента в эту таблицу и изменение первичного ключа может сломать проект (подумайте о внешних ключах), или, может быть, вам придется делать десятки изменений в коде. Если ваша единственная цель - свести к минимуму url/querystring, тогда это кажется хорошим решением для этого без риска взлома вещи. – Skorpioh

 Смежные вопросы

  • Нет связанных вопросов^_^