Если это задача и вам нужны готовые ответы с решениями, то вы не по адресу.
Где ваши личные рассуждения? Где ваши предположения и на что вы опирались их делая?
Я могу тут сделать подсказку: что такое "код запаса товара", для чего он нужен как его интерпретировать в контексте заданных вами вопросов. Ещё с стоит подумать о дате и времени в этой таблице. Следовало бы упомянуть, что это не журнал состояний, а снимок состояния складов.
а что, такой простой вариант БД может быть настолько неоднозначно интерпретирован относительно нормализации данных, что без посторонних рассуждений/взглядов не обойтись?
это же учебный вариант, а не какой-то сложный реальный проект
Filarru, сначала обсуждают выполняемые функции (функциональную модель), потом смотрят, какие потоки данных обрабатывает функция, и уже потом обращают внимание как эти данные хранят.
alexalexes, да оно как бы понятно, но когда речь идет об учебных примерах, у нас зачастую никакая функциональность не описывается, даже более того - её и не рекомендуют рассматривать в таком контексте
но будем считать, что аналитика предполагается по-умолчанию, чтобы понимать КОГДА и ИЗ ЧЕГО состоял наш складской запас, а также как он менялся с ходом времени
Что значит "посторонних"? Что вы под этим имеете в виду?
Любые данные и любая структура имеют какой-то смысл и цель. Даже учебные примеры должны вас научить чему-то конкретному. Решать какого-то рода задачи, например.
Ещё раз поясню. Тут обычно никто не будет за вас решать учебные примеры. Особенно если вы не потрудились над ними самостоятельно.
Это не цель данного ресурса. Тут помогут вам не ошибиться, натолкнут на мысль, исправят в ошибках, которые вы не можете распознать в своих рассуждениях.
а что, такой простой вариант БД может быть настолько неоднозначно интерпретирован относительно нормализации данных
Если вы не говорите какие именно данные хотите хранить, то да.
Это не вариант БД, это пример, от которого "отрезали лишнее", но для корректного ответа нужно либо уточнить вопрос, либо сделать некоторые допущения, о которых явно сказать в ответе.
Если вам нужен журнал с историческими данными о состояниях остатков на любой момент времени, то это одна ситуация и одно решение. Если нужно просто хранить в такой структуре текущее состояние, то другая.
Сергей П, так пример то мой личный, а не взятый из учебника. И тот факт, что я пришел с вопросом о нормализации БД - этого всего мало для ответа?
Очевидно же, что если бы не было вопроса в голове - его и тут бы не было.
Задача тут проста:
нарушается ли нормализация таким образом, если мы через дату/время можем извлечь конкретное количество и наоборот?
Т.е. вопрос про нормализацию, а не про проектирование в целом.
А дата/время нужны для анализа данных по необходимости.
Однако тут и смущает момент (на мой взгляд), что через дату/время тогда вообще много чего конкретного можно получить и при других полях и другой предметной области. Это все о 3НФ.
Filarru, сделайте дату время одним таймштампом. Так с ними работать будет неудобно.
Вы так и не ответили на мой вопрос, или я пропустил? Вы состояние храните или историю?
Сергей П, я видимо не в состоянии вам точно ответить.
Скажу тогда немного иначе - хранить нужно дату/время обновления количествя товаров.
Т.е. произошло событие при котором какое-то количество какого-то товара изменилось и появилась новая запись с датой и временем.
Потом мы в теории можем запросить эти данные (т.е. количество конкретного товара на конкретную дату) и использовать это для анализа динамики.
Сергей П, это я к чему. Если храните только одно состояние всех складов, то "код запаса"не нужен, вопрос решается составным идентификатором из идентификатора склада и идентификатора товара. Кодзапаса будет синтетическим и не будет нести полезной информации.
Сергей П, это требует отдельного внимания.
Но что все таки с нормализацией (3NF) и такими типами данных как дата/время?
Может я в самой сути нормализации чего-то не понял (зависимость одного неключевого столбца от другого)?
Но очевидно что по дате/времени можно вообще информацию из любого другого неключевого столбца получить. Или я ошибаюсь?
Примерно схожая проблема с 1NF и типом данных SET/ENUM.
я видимо не в состоянии вам точно ответить.
Скажу тогда немного иначе - хранить нужно дату/время обновления количествя товаров.
Т.е. произошло событие при котором какое-то количество какого-то товара изменилось и появилась новая запись с датой и временем.
Потом мы в теории можем запросить эти данные (т.е. количество конкретного товара на конкретную дату) и использовать это для анализа динамики.
Это, вероятно, похоже на историю.
Смотрите в чем вопрос.
Если по конкретному складу и по конкретному товару вы храните не одну запись остатка, а всю цепочку, то это называется "журнал", "история" и т.д. В этом случае нужен обычно ещё один идентификатор. Как у вас в схеме.
Такая структура данных позволяет в любой момент рассмотреть динамику расхода товара, отобразить запасы а графике по времени, и т.д. Минусы в описанной схеме есть. Основной - это скорость доступа к снапшоту текущего состояния. Для быстрого доступа к снапшоту текущего состояния нужно добавлять ещё флаг финального состояния и делать с ним индекс. Это компромиссный вариант, поскольку при изменении запаса на складе вам не достаточно добавить одну запись, вам нужно ещё и обновить предыдущий хвостовой элемент, а при этом дважды изменятся индексы.
Правильнее поступать по-другому. Хранить журналы в отдельной таблице, а снапшот в отдельной. Это уже не будет соответствовать формальным требованиям нормализации, НО, зато это будет хорошо и быстро работать на практике.
В реальности мы всегда выбираем компромиссы между избыточностью и скоростью, между сложностью и надёжностью, между реплицируемостью и доступностью... Прочитайте про CAP-теорему.
Во многих случаях прибегают к сознательной денормализации данных в БД, чтобы ускорить некоторые запросы в тысячи раз, на порядки.
Если задача автоматизированной системы строить график уровня запаса (выполнять функцию подсистемы аналитики), то такая схема полностью уместна.
PS:
Но в реальной жизни у вас на месте таблички "Запас товара" будет "История завоза и вывоза товара", по которой у вас не будет явной цифры остатка товара, вам придется всегда его считать по sum() за период времени.