- 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)
);
последствия неправильно спроектированной БД
ХУЙНЯ, ХУЙНЯ, ХУЙНЯ!
"SELECT * FROM ..."
Реально не догадываетесь?
1. В 99% случаях используются данные не из всех колонок. Так нафига гонять лишние данные по сети?
2. Таблица в базе, если проект живой, со временем изменяется, а значит могут появиться новые колонки, которые в существующих запросах нафиг не упёрлись. Если приложение проверяет постоянно на соответствие метаданных, то может слететь по "metadata is out of synchronization".
3. Больше всего убивает, когда хотят посчитать кол-во строк, и для этого затягивают всё на уровень приложения с "SELECT * FROM..." и там считают :-\
А вообще, как показывает практика, если человек пишет "SELECT * FROM..." на уровне приложения - он слабо представляет роль СУБД в общей архитектуре.
Вот пример, когда в двух заджойненных таблицах повторяющееся поле id, но никакого батхерта не происходит (за счёт использования u.id):
SELECT *
FROM users u
JOIN achievements ach ON ach.uid = u.id
WHERE u.id = ?
ИМХО лучше в 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); // вернёт тот-же обьект из собственного кеша
Тогда уж на уровне приложения в DAO вычитываем справочник запросом:
SELECT name, price, icon, name, damage_bonus FROM ref_items WHERE id=?
А через классы врапперы, описывающие доменную модель, обращаемся к конкретным полям.
ЗЫЖ Да и кеширование на СУБД - это ещё та серая магия. Надеяться на кеш архитектурно - моветон.
т.е. в этом случае разница между
SELECT name, price, icon, name, damage_bonus
и SELECT * только в человеческом факторе, программно будет выполнятся все-равно одна и та-же логика.
Как по мне в DAO цена перечисления полей себя не оправдывает. Лично я бы для них сделал исключениее в правиле "никогда не пиши SELECT *"
$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);
$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));
Или юзер не может иметь более двух однотипных предметов? :)
Одно из двух...
P.S. Вот тут я погорячился. Может.
За счёт этого на один тип ресурса у одного игрока может быть только одна запись в БД, т.е. для таблицы user_storage PRIMARY KEY состоит из (user_id, item_id).