#mysql #database-design
#mysql #проектирование базы данных #база данных-проектирование
Вопрос:
Я новичок в базах данных и mysql и пытаюсь разобраться, как спроектировать свою базу данных. Я работаю над тестовым проектом, где люди могут просматривать, какие элементы у них есть в некоторых шкафах. Таким образом, пользователь может щелкнуть по шкафу и увидеть все полки внутри него и все предметы для каждой полки.
Пока я разобрался, мне понадобятся следующие таблицы:
Item Table
Item ID, Item Name
Shelf Table
Shelf ID, Shelf Number
Cabinet Table
Cabinet ID, Cabinet Name
Вопрос, на котором я застрял, заключается в том, какие реляционные таблицы мне понадобятся? Я уверен, что это действительно легко для кого-то!
Могу ли я создать четвертую таблицу, которая содержит что-то вроде:
ItemID, Shelf ID, Cabinet ID
Будет ли это иметь смысл, чтобы я мог запросить все полки в шкафу и их элементы для каждой полки? Я уверен, что на это очень легко ответить, но у меня болит мозг! Мне сказали использовать MyISAM в качестве механизма хранения, если это поможет.
Спасибо
Редактировать:
Спасибо, еще один вопрос, если вы не возражаете. Знаете ли вы, как получить все элементы на всех полках, чтобы они отображались в html следующим образом:
<div id="shelf-1"><p>spoon</p><p>fork</p>
<div id="shelf-2"><p>knife</p></div>
У меня есть следующее, которое, кажется, работает, но, прочитав, я не думаю, что хорошей практикой является цикл внутри запроса:
$cabinetID = $_GET['cabinetid'];
$sqlShelf = sprintf(' SELECT shelf_id
FROM shelf
INNER JOIN cabinet ON (cabinet.cabinet_id = shelf.cabinet_id)
WHERE cabinet.cabinet_id = %s', $cabinetID);
$resultShelf = mysql_query($sqlShelf);
while($shelf = mysql_fetch_assoc($resultShelf)) {
$shelfID = $shelf['shelf_id'];
$sqlItem = sprintf('SELECT *
FROM item
INNER JOIN shelf ON (item.shelf_id = shelf.shelf_id)
INNER JOIN cabinet ON (cabinet.cabinet_id = shelf.cabinet_id)
WHERE cabinet.cabinet_id = %s
AND shelf.shelf_id = %s', $cabinetID, $shelfID);
$resultItem = mysql_query($sqlItem);
echo('<div>');
while($item = mysql_fetch_assoc($resultItem)) {
echo('<p>' . $item['item_name'] . '</p>' . PHP_EOL);
}
echo('</div>');
Ответ №1:
Подумайте об этом с точки зрения английского языка, прежде чем писать SQL.
У вас может быть много шкафов; в каждом шкафу ноль или более полок; на каждой полке может быть ноль или более элементов.
Полка может находиться только в одном шкафу одновременно; элемент может находиться только на одной полке одновременно.
Итак, я бы спроектировал это как три таблицы, с отношениями «один ко многим» для двух из них.
CREATE TABLE IF NOT EXISTS cabinet
(
cabinet_id bigint not null auto_increment,
primary key(cabinet_id)
);
CREATE TABLE IF NOT EXISTS shelf
(
shelf_id bigint not null auto_increment,
cabinet_id bigint,
primary key(shelf_id),
foreign key(cabinet_id) references cabinet(cabinet_id) on delete cascade on update cascade
);
CREATE TABLE IF NOT EXISTS item
(
item_id bigint not null auto_increment,
shelf_id bigint,
primary key(item_id),
foreign key(shelf_id) references shelf(shelf_id) on delete cascade on update cascade
);
Вот пример запроса, который предоставит вам все элементы в определенном кабинете (только что попробовал — отлично работает):
SELECT item.item_id, cabinet.cabinet_id
FROM item
INNER JOIN shelf ON (item.shelf_id = shelf.shelf_id)
INNER JOIN cabinet ON (cabinet.cabinet_id = shelf.cabinet_id)
Комментарии:
1. Спасибо, это здорово, помогает думать об этом таким образом. Могу ли я быть действительно дерзким и получить пример запроса!
2. Это мне не позволит, у меня недостаточно репутации : (
Ответ №2:
Вам понадобятся две таблицы между этими тремя таблицами для хранения данных, соответствующих отношениям.
Shelf_Cabinet Table
ShelfID, CabinetID
и
Item_Shelf Table
ItemID, ShelfID
Комментарии:
1. Это верно, если между полкой и шкафом, элементом и полкой существуют отношения «многие ко многим», но я не верю, что физика позволит это.