- 1
- 2
- 3
- 4
- 5
$try = $db->getRow(
"SELECT * FROM user_{$name}, item_{$name} ".
"WHERE user_{$name}.usr_id=? AND user_{$name}.{$type}_id=? AND user_{$name}.{$type}_id=item_{$name}.{$type}_id",
array($user->usr_id, $id)
);
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+148
$try = $db->getRow(
"SELECT * FROM user_{$name}, item_{$name} ".
"WHERE user_{$name}.usr_id=? AND user_{$name}.{$type}_id=? AND user_{$name}.{$type}_id=item_{$name}.{$type}_id",
array($user->usr_id, $id)
);
последствия неправильно спроектированной БД
guest 03.09.2013 17:31 # −4
ХУЙНЯ, ХУЙНЯ, ХУЙНЯ!
DBdev 04.09.2013 11:23 # +2
"SELECT * FROM ..."
anonimb84a2f6fd141 04.09.2013 16:44 # −3
DBdev 05.09.2013 10:28 # +3
Реально не догадываетесь?
1. В 99% случаях используются данные не из всех колонок. Так нафига гонять лишние данные по сети?
2. Таблица в базе, если проект живой, со временем изменяется, а значит могут появиться новые колонки, которые в существующих запросах нафиг не упёрлись. Если приложение проверяет постоянно на соответствие метаданных, то может слететь по "metadata is out of synchronization".
3. Больше всего убивает, когда хотят посчитать кол-во строк, и для этого затягивают всё на уровень приложения с "SELECT * FROM..." и там считают :-\
А вообще, как показывает практика, если человек пишет "SELECT * FROM..." на уровне приложения - он слабо представляет роль СУБД в общей архитектуре.
bormand 05.09.2013 12:22 # +1
xara 05.09.2013 12:39 # +2
Вот пример, когда в двух заджойненных таблицах повторяющееся поле id, но никакого батхерта не происходит (за счёт использования u.id):
SELECT *
FROM users u
JOIN achievements ach ON ach.uid = u.id
WHERE u.id = ?
bormand 05.09.2013 12:52 # 0
xara 05.09.2013 12:54 # 0
ИМХО лучше в 5 разных местах использовать:
SELECT * FROM ref_items WHERE id=?
чем запросы вида:
SELECT name, price FROM ref_items WHERE id=?
SELECT icon, name FROM ref_items WHERE id=?
SELECT damage_bonus FROM ref_items WHERE id=?
К тому-же такой подход хорошо сочитается с кешированием-в-модели.
$item = Item::get($itemId); // выймет данные из SELECT * FROM ref_items WHERE id=?
$item = Item::get($itemId); // вернёт тот-же обьект из собственного кеша
DBdev 05.09.2013 14:31 # +2
Тогда уж на уровне приложения в DAO вычитываем справочник запросом:
SELECT name, price, icon, name, damage_bonus FROM ref_items WHERE id=?
А через классы врапперы, описывающие доменную модель, обращаемся к конкретным полям.
ЗЫЖ Да и кеширование на СУБД - это ещё та серая магия. Надеяться на кеш архитектурно - моветон.
xara 05.09.2013 14:51 # 0
т.е. в этом случае разница между
SELECT name, price, icon, name, damage_bonus
и SELECT * только в человеческом факторе, программно будет выполнятся все-равно одна и та-же логика.
roman-kashitsyn 05.09.2013 15:00 # +1
DBdev 05.09.2013 15:17 # 0
xara 05.09.2013 16:19 # 0
xara 05.09.2013 15:20 # 0
Как по мне в DAO цена перечисления полей себя не оправдывает. Лично я бы для них сделал исключениее в правиле "никогда не пиши SELECT *"
xara 04.09.2013 11:51 # 0
$try1 = $db->getRow("SELECT * FROM user_{$name} WHERE usr_id=? AND {$type}_id=?", array($user->usr_id, $id));
$try2 = $db->getRow('SELECT * FROM item_{$name} WHERE {$type}_id=?', $id);
$try = array_merge($try1, $try2);
xara 04.09.2013 12:10 # 0
$userItem = $db->getRow("
SELECT *
FROM user_storage us
JOIN ref_items ri ON ri.id = us.item_id
WHERE us.uid=? AND us.item_id=?
", array($user->id, $itemId));
bormand 04.09.2013 12:24 # 0
Или юзер не может иметь более двух однотипных предметов? :)
Одно из двух...
bormand 04.09.2013 12:50 # 0
P.S. Вот тут я погорячился. Может.
xara 04.09.2013 12:58 # 0
За счёт этого на один тип ресурса у одного игрока может быть только одна запись в БД, т.е. для таблицы user_storage PRIMARY KEY состоит из (user_id, item_id).
bormand 04.09.2013 13:16 # 0