![]() |
Модераторы: skyboy |
![]() ![]() ![]() |
|
fridkaratel |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
Задался вопросом - использование CHAR в качестве ключа PRIMARY...
Создал тестовую таблицу на 100 000 строк - разницы на локальном сервере не заметил. То есть, что выборка по INT (11), что выборка по CHAR (12) - дала одинаковые результаты. Хотелось бы узнать, какие есть последствия использования CHAR в качестве ключа? --------------------- Вот пример, где легче работать с CHAR чем с INT. Есть пользователи, есть товары и есть заказанные пользователем товары. Пользователь хочет изменить количество с 10 на 20. При работе с INT необходимо выбрать все товары, заказанные пользователем, чтобы узнать OrderCommodityId в базе. При работе с CHAR нет необходимости выбирать все товары - OrderCommodityId будет всегда UserId + '_' + CommodityId. То есть, при CHAR в качестве PRIMARY KEY не надо делать выборку - а просто одним запросом INSERT ON DUPLICATE KEY UPDATE. --------------------- Посчитаем... Пользователей: 1 000 000 Товаров: 100 000 Получается, что длина макс. OrderCommodityId будет 1000000_100000 - это 15 знаков. --------------------- Выборка по Id будет всегда происходить при условии 100% равенства, т.е. не будет LIKE и т.п. --------------------- Также вижу, что в таком случае нет необходимости удалять значения из БД. Например, пользователь заказал товар. В таблицу добавилась строка с OrderCommodityId=100_999 и количеством. Потом пользователю выдали товар, и количество изменили на 0. В таких случаях, таблица не будет фрагментироваться... --------------------- Если в обработке задействованы, например, 3 таблицы, то опять же надо делать выборку из этих двух таблиц, чтобы получить Id элемента в каждой из них. В случае с CHAR мы через PHP-скрипт генерируем его Id, разделяя нижним слешем, и всё. А потом INSERT ON DUPLICATE KEY UPDATE... --------------------- Что скажете по всему этому? Очень хочется узнать вашего мнения, а также за и против... |
|||
|
||||
lomaster |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 27.5.2012 Репутация: нет Всего: 2 |
Вы лучше почитайте про реляционные базы. Тогда лайки, фрагментации и т.п. в голову лезть небудут. |
|||
|
||||
fridkaratel |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
Да, но...
Например, есть товар: ItemId=123 и Sku=SK91 (Sku - это артикул). Есть несколько складов, где есть этот товар. При выдаче товара я выбираю склад, откуда его выдать. В итоге, мне нет необходимости его искать через SELECT. Достаточно составить ключ из ID склада и ID товара - и всё. А далее через INSERT UPDATE обновить количество на складе. Что выдать 1 товар, что выдать 100 товаров - не надо их выбирать через SELECT WHERE IN (...). Мне вообще не надо знать ID для этого товара на складе. Я его генерирую через PHP и тем же INSERT UPDATE обновляю. Как-то вот так... ![]() Мне кажется, это удобно и... понятней, нежели выбирать ID... Но я сомневаюсь в таком решении, потому как не специалист в области БД, поэтому и попросил советов и рекомендаций... ;-) |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
а что тебе мешает это сделать при составном первичном ключе на двух полях — userID и commodityID? тем более, что "вывести все заказы данного пользователя" — тоже потенциально не редкий запрос, в случае составного ключа. а вот в случае строкового ключа — все сложнее. особенно, если у тебя в значениях "1_1245" и "10001_5640" часть под userID имеют разную длину — тогда и оптимизация не поможет, будет так же быстро, как Like "10001_%" |
|||
|
||||
lomaster |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 27.5.2012 Репутация: нет Всего: 2 |
Здается мне что у автора склад неправильно сделан, вот и ищет как правильно, но не в той степи.
|
|||
|
||||
fridkaratel |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
@skyboy:
В таблице будет столбец с Id пользователя... И с Id товара... То есть примерно так: - StoreCommId = CHAR (12) - StoreId - CommId - StoreQty Если StoreCommId - это INT (11) с автоувеличением, то в случае обновления более одного товара на складе придётся: А) Или сразу выбрать CommId всех товаров, а потом делать INSERT ON DUPLICATE UPDATE Б) Обновлять без проверки дубликатов, а через WHERE StoreId=A AND CommId=B В случае же использования CHAR в качестве PK отпадёт выборка товаров со склада Мне надо будет в PHP-скрипте сгенерировать StoreCommId из тех значений, которые мне уже известны - StoreId и CommId... Как то так... ;) ------------- @lomaster Здается мне что у автора склад неправильно сделан, вот и ищет как правильно, но не в той степи. Я не являюсь специалистом базах данных, потому не могу точно сказать о правильности своего выбора. Но я стараюсь, учусь ![]() Задал вопрос в поиск, но особо точных ответов никто не дал... Основным минусом CHAR в качестве PK называют то, что при JOIN'ах будет медленней работать, чем при использовании INT. Но мне JOIN'ов и не надо... Мне надо, фактически, обновлять данные запросом INSERT UPDATE без доп. выборки SELECT'ом тех Id, которые затрагиваются. В моём случае, я их могу предугадать со 100% уверенностью... Во-от... |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
я тебе уже писал, что составной уникальный ключ на StoreId + CommId позволяет тебе поступать так же. то есть, SELECT из этой таблицы не происходит? сугубо вставка/обновление? какая странная таблица ![]() |
|||
|
||||
lomaster |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 27.5.2012 Репутация: нет Всего: 2 |
|
|||
|
||||
fridkaratel |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
@skyboy:
То есть, получается, если я создам UNIQUE KEY = StoreId + CommId, то мне можно будет точно также делать INSERT ON DUPLICATE KEY UPDATE? Если да, то это здорово! Я просто не знал об этом ![]() Тогда многие вопросы отпадают, в т.ч. и использование CHAR в качестве PRIMARY KEY.
SELECT происходит. Чтобы выдать товар, происходит LEFT JOIN с выборкой кол-ва на складе, чтобы не выдать больше, чем там есть. Но JOIN происходит не по PRIMARY KEY, а по Id склада и артикулу товара. ---------------------------- @lomaster
Чтобы обновить кол-во на складе, зная StoreCommId... Но если можно так, как сказал skyboy, то StoreCommId как-бы и не нужен уже ![]() Это сообщение отредактировал(а) fridkaratel - 27.11.2012, 06:45 |
||||||
|
|||||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
||||
|
||||
fridkaratel |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
@skyboy:
Большое спасибо за ответы и советы! ;-) Сегодня почитал про ключи и узнал много нового ![]() Есть попутный вопрос (перед закрытием темы)... Чтобы выбрать доступные для резерва товары, я выполняю такой запрос:
Чтобы выбрать долги клиенту, я выполняю такой запрос:
Возникают два вопроса: 1. Не слишком ли они сложные и.. 2. Можно ли их упростить? Комментарий: - У каждого клиента есть менеджер, который его обслуживает, поэтому он учавствует и в резерве товара. - Эти два запроса я подкорректировал для наглядности. То есть, не надо их сопоставлять один с другим. Можно сказать, эти запросы выполняются к двум разным БД с разными структурами таблиц ![]() Это сообщение отредактировал(а) fridkaratel - 27.11.2012, 09:43 |
||||
|
|||||
fridkaratel |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 221 Регистрация: 22.10.2007 Где: Error connect to MySQL Da... Репутация: нет Всего: нет |
В качестве эпилога...
С запросами разобрался. С использованием CHAR в качестве PRIMARY KEY тоже... Вывод: Не использовать CHAR в качестве PK - использовать составной UNIQUE INDEX по тем столбцам, из которых хотелось сформировать PRIMARY KEY. То есть, если StoreId=3 и CommId=1000, то вместо PRIMARY KEY (AS CHAR) = 3_1000 сделать UNIQUE INDEX на StoreId + CommId. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | MySQL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |