Управление версиями таблиц (исторические таблицы) и таблицы заказов - PullRequest
0 голосов
/ 08 октября 2011

Если я добавлю новый продукт в таблицу products или изменим данные - он автоматически добавится в products_history. Это делается триггером.

Когда клиент размещал заказ, нет необходимости дублировать название продукта в таблице order_products.

Чтобы получить название и цену продукта из таблицы order_products - вы будете запрашивать из таблицы products_history, а не из таблицы products

Примечание: я показываю простые таблицы для демонстрации.

См. Следующие таблицы и результат:

mysql> select * from products;
+----+------------+-------+---------------------+
| id | name       | price | timestamp           |
+----+------------+-------+---------------------+
|  1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
|  2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
+----+------------+-------+---------------------+

mysql> select * from products_history;
+----+------------+-------+---------------------+
| id | name       | price | timestamp           |
+----+------------+-------+---------------------+
|  1 | Product 23 |  2.00 | 2011-10-08 18:55:44 |
|  2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
|  1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
+----+------------+-------+---------------------+

Таблицы заказов:

mysql> select * from `order`;
+----+-------------+
| id | total_price |
+----+-------------+
|  1 |     9999.00 |
+----+-------------+

mysql> select * from order_products;
+----+----------+------------+---------------------+
| id | order_id | product_id | product_timestamp   |
+----+----------+------------+---------------------+
|  1 |        1 |          2 | 2011-10-08 18:55:44 |
|  2 |        1 |          1 | 2011-10-08 18:55:53 |
+----+----------+------------+---------------------+

Чтобы получить название продукта и цены из таблицы заказов:

SELECT order.total_price, products_history. * FROM  `order` 
   LEFT JOIN order_products ON order_products.order_id = order.id
   LEFT JOIN products_history ON products_history.id = order_products.product_id
             AND products_history.timestamp = order_products.product_timestamp
WHERE order.id =1 

Результат

+-------------+------+------------+-------+---------------------+
| total_price | id   | name       | price | timestamp           |
+-------------+------+------------+-------+---------------------+
|     9999.00 |    2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
|     9999.00 |    1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
+-------------+------+------------+-------+---------------------+

Кажется, работает нормально.

Есть ли какой-то серьезный недостаток в этом дизайне или что я мог бы сделать по-другому?


Второй вопрос о дополнениях ... Товар может иметь дополнения или дополнения. Нужно ли использовать версию для extra_group таблицы? У меня есть только версия для таблицы extra.

См. Следующие таблицы:

mysql> select * from extra_group;
+----+------------------+
| id | name             |
+----+------------------+
|  1 | Extras Group One |
+----+------------------+

mysql> select * from extras;
+----+---------+-------+---------------------+
| id | name    | price | timestamp           |
+----+---------+-------+---------------------+
|  1 | Extra 1 |  0.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.31 | 2011-10-08 18:58:10 |
+----+---------+-------+---------------------+

mysql> select * from extras_history;
+----+---------+-------+---------------------+
| id | name    | price | timestamp           |
+----+---------+-------+---------------------+
|  1 | Extra 1 |  0.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.31 | 2011-10-08 18:58:10 |
+----+---------+-------+---------------------+


mysql> select * from products_extras;
+----+------------+----------------+
| id | product_id | extra_group_id |
+----+------------+----------------+
|  1 |          2 |              1 |
+----+------------+----------------+
//This mean Product ID 2 have extras from  extra_group_id = 1

Таблица заказов на дополнительные услуги:

mysql> select * from order_products_extras;
+-------------------+----------+---------------------+
| order_products_id | extra_id | extra_timestamp     |
+-------------------+----------+---------------------+
|                 1 |        1 | 2011-10-08 18:57:55 |
|                 1 |        2 | 2011-10-08 18:58:10 |
+-------------------+----------+---------------------+

// Клиент выбрал extra_id 1 и 2 из product_id 1

Используйте аналогичный запрос, как указано выше, чтобы получить дополнительное имя и цену из таблицы extras_history

Триггеры

CREATE TRIGGER `extras-afterinsert` AFTER INSERT ON `extras`
FOR EACH ROW BEGIN
    INSERT INTO `extras_history` VALUES (NEW.`id`, NEW.`name`, NEW.`price`, NEW.`timestamp`);
END
|
CREATE TRIGGER `extras-afterupdate` AFTER UPDATE ON `extras`
FOR EACH ROW BEGIN
    INSERT INTO `extras_history` VALUES (NEW.`id`, NEW.`name`, NEW.`price`, NEW.`timestamp`);
END

И аналогичные для products_history таблицы.

Я трачу свое время, используя исторические таблицы, я должен просто дублировать имена / цены в order_products и order_products_extras таблицы?

Примечание. В таблицах procucts и extras будет более 100 000 строк и более 1000 заказов в день.

Ответы [ 2 ]

0 голосов
/ 09 октября 2011

Я действительно не мог понять, чего вы пытаетесь достичь с помощью таблиц истории.Если цена продуктов быстро меняется и вы хотите сохранить базовую цену продуктов в текущее время, почему бы не поместить ее в order_product?

orders :
order_id / created_at / status (PK : order_id)

order_products : 
order_id / product_id / quantity /  product_price (PK : order_id, product_id)

, чтобы вам не приходилось каждый раз присоединяться к product_history.Вы можете сделать ту же денормализацию для дополнительных функций, а также.

PS: старайтесь не использовать зарезервированные слова, такие как "порядок" в именах таблиц / столбцов, это может привести к ошибкам.

0 голосов
/ 09 октября 2011

Одна опасность, связанная с записью только одной временной отметки, заключается в том, что трудно определить, какая последняя запись для данного заказа.Вы должны использовать подвыбор или функцию.Я бы порекомендовал иметь start_timestamp и finish_timestamp, причем последний будет NULL для последней записи.Когда запись становится историей, она заполняет свой файл finish_timestamp. Я уверен, что есть и другие способы решения этой проблемы, но мне кажется, что это самый простой способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...