Консультация № 172482
22.09.2009, 16:30
0.00 руб.
0 11 2
Здравствуйте, уважаемые эксперты!

Пожалуйста помогите ответить на мой вопрос:
Я проектирую БД склада на СУБД Access: Товар на складе хранится в коробках. Каждая коробка имеет уникальный номер. В каждой коробке может хранится несколько товаров, каждый товар может храниться в нескольких коробках. Склад состоит из ячеек - каждая ячейка имеет уникальный номер. В каждой ячейке может стоять только одна коробка. Коробки могут не стоять ни в какой ячейке. Ячейки могут быть пустыми.

У меня в итоге получилось 4 таблицы:
1. Товары (Номер товара-ключ.поле, НАзвание товара)
2. Коробки (Номер коробки - ключ.поле,Комплектовщик)
3. Ячейки склада (Номер ячейки - ключ. поле)
4. Товары в коробках (Номер коробки-ключ, Номер товара -ключ,Количество товара)

Таблицы 'Товары' и 'Коробки' связаны через промежуточную таблицу 'Товары в коробках' одно-многозначными связями.
А вот каким образом связать 'Коробки' и 'Ячейки' я не могу понять. По смыслу между этими таблицами должна быть связь один-к-одному (в одной ячейке может находиться только одна коробка). Но если добавлять из одной таблицы ключевое поле в другую таблицу в качестве внешнего ключа, то получается связь один-ко многим. Если реализовывать связь через промежуточную таблицу 'Размещение коробок' то связь между этими таблицами получается много-многозначная'. Пожалуйста, подскажите, как правильно решить этот вопрос.

Заранее благодарю,
Алексей

Обсуждение

Неизвестный
22.09.2009, 17:09
общий
это ответ
Здравствуйте, Alexey Sergeev.

Мне кажется, судя по условиям задачи, получается, что таблица "Коробки" может иметь поле "Номер ячейки" (может иметь значение или быть NULL).

Что касается таблицы "Ячейки", то она, кроме номера ячейки (ключевое поле) должна содержать какие-то характеристики ячеек (а иначе она, вроде бы, не нужна; можно будет создать такое представление на основе других таблиц).

Если же есть строгое условие, что в одной ячейке должно стоять не больше одной коробки, то, наоборот, можно в таблице "Ячейки" создать поле "Номер коробки" (которая в ней стоит), а в таблице "Коробки" тогда поле "Номер ячейки" добавлять не нужно.

Если я что-то не точно понял вопрос, напишите, пожалуйста, уточнение в мини-форуме.

Успехов Вам!
Неизвестный
22.09.2009, 18:07
общий
это ответ
Здравствуйте, Alexey Sergeev.
Может сделать немного по-другому? Это добавит дублирующуюся информацию в таблицы, но станет проще получать информацию о текущем состоянии.

Yach ( Ячейка ) данные о текущих ячейках и их загрузке
Kod ключ, код ячейки
Kor код помещенной в ячейку коробки, если пустая =0
Name наименование ячейки ( шифр, инвентарный номер или ч-л подобное, вдруг пригодится )

Kor ( Коробок ) данные о коробках
Kod ключ, код коробки
Yach код ячейки, в которую помещен коробок, если никуда =0
Kompl комплектовщик ( лучше код комплектовщика и добавить таблицу для них )
Name наименование коробки ( шифр, инвентарный номер или ч-л подобное )

Tov ( Товар ) справочник товаров
Kod ключ, код товара
Name наименование

Skl ( Склад ) данные о паковке товаров в коробки
Kor код коробки
Tovar код товара
Kol количество товара в коробке
в теории, здесь хранится текущее состояние упаковок, поэтому старые данные удаляются.

я бы еще добавил справочник партий товара. это усложнит базу, но можно будет отследить какие старые товары не были использованы и почему вместо них использовались товары из нового поступления.
Part ( Партия )
Kod код партии
Tov код товара
Dpost дата поступления
Kol количество
Ostat остаток на складе ( можно придумать еще поля )

тогда справочник склада немного изменится
Skl ( Склад ) данные о паковке товаров в коробки
Kor код коробки ( в теории, не может быть =0 , т.к весь товар расфасован в коробки, но ошибкой не будет - напишет "без коробки" если добавить пустые записи как написано в примечании ниже )
Part код партии товара ( не может быть =0 )
Kol количество товара в коробке ( не может быть =0 , иначе нужно удалить запись )

За счет дублирования информации в двух таблицах о заполнении ячеек коробками и о загрузке коробок в ячейки, отпадает необходимость в связи между ними. Ключевые поля лучше делать длинное целое, но не счетчик, а заполнять это поле вручную ( сначала найти максимальное значение в таблице и новой записи присвоить на единицу больше ) .
Еще было бы неплохо добавить "нулевые записи" в справочники ( значение ключа =0 ) :
Yach ( 0 , 0 , "без ячейки" )
Kor ( 0 , 0 , 0 , "без коробки" )
Tov ( 0 , "не выбран" )
чтобы при связи таблиц не выпадали строки, в которых второй ключ =0 ( если ячейка пустая или коробка не в ячейке )

Не знаю как там прямо в Access, я работаю через клиентское приложение на VB. Вот примеры запросов

Текущее состояние ячеек ( если ячейка свободна - во втором поле будет "без коробки" )
select y.Name,k.Name from yach y inner join kor k on k.kod=y.kor

Занятые ячейки
select y.Name,k.Name from yach y inner join kor k on k.kod=y.kor where y.kor>0

Текущее состояние коробок ( где находятся, может быть "без ячейки" )
select k.Name,y.Name from kor k inner join yach y on y.kod=k.yach

Занятые коробки
select k.Name,y.Name from kor k inner join yach y on y.kod=k.yach where k.kod in ( select kor from skl group by kor )

Состояние коробок ( наличие в них товара и его количество )
select k.Name, y.Name, t.Name, sum ( s.kol ) as [kol]
from ( ( ( kor k inner join yach y on y.kod=k.yach ) inner join skl s on s.kor=k.kod ) inner join part p on p.kod=s.part ) inner join tov t on t.kod=p.tov
group by k.Name, y.Name, t.Name
это теоретически. реально запрос не проверял.

Фактически, все селекты это дополнительные таблицы для удобства отображения данных ( вкладка View в базе ) .

Если создатите базу и заполните данными, то можете отправить на адрес jones@hte.vl.net.ua и написать, какие еще запросы нужны - напишу в ответе.

С уважением.
Неизвестный
22.09.2009, 18:10
общий
во. целый час ответ писал. когда начинал, еще не было ответов. это не зачтется как повтор?
Неизвестный
22.09.2009, 18:12
общий
Филатов Евгений Геннадьевич:
Евгений Геннадиевич, я буду только рад, если вдруг действительно случится повтор
Неизвестный
22.09.2009, 20:38
общий
Гуревич Александр Львович:
Уважаемый Александр Львович,
Большое спасибо за ваш ответ. По существу вопроса могу сказать следующее. Обойтись без таблицы "Ячейки" не получится, так как в ней содержится конечное множество конкретных номеров ячеек, то есть это по-сути перечень тех ячеек, которые существуют на складе. Не будь такой таблицы, то возможно было бы приписать к коробке с товарами несуществующий адрес ячейки. Добавление поля "номер ячейки" в таблицу "Коробки" в данной ситуации, к сожалению, также не подходит. При таком добавлении между таблицами "Коробки" и "Ячейки" устанавливается связь многие-к одной, то есть возможно для многих коробок указать один и тот же номер ячейки (по условиям в одной ячейке может быть только одна коробка). Если же создать поле "Номер коробки" в таблице "Ячейки", то получится, что одна коробка может стоять в нескольких ячейках, что также противоречит условиям задачи.
По смыслу взаимоотношений сущностей "Коробки" и "Ячейки", на мой взгляд, между ними имеется связь один-к-одному, причем необязательная в обоих направлениях. Если бы можно было эту связь выразить в виде дополнительного отношения "Размещение коробок в ячейках", да еще при этом так, чтобы эта связь была один-к-одному, то это было бы на мой взгляд оптимальным решением. Можно было бы в этом связующем отношении указать даже дополнительные атрибуты (кто поставил коробку в ячейку, когда она туда была поставлена и т.д.).
Если у Вас есть соображения, как такую связь реализовать, пожалуйста, напишите...
Неизвестный
22.09.2009, 21:06
общий
Филатов Евгений Геннадьевич:
Здравствуйте, Евгений Геннадьевич,
Спасибо за Ваш ответ.
Пожалуйста, подскажите, с какими таблицами связана таблица "yach" в предложенном вами проекте?

И еще один момент - Вы пишите: "Еще было бы неплохо добавить "нулевые записи" в справочники ( значение ключа =0 )". Возможно ли, чтобы в СУБД поле уникального ключа принимило неопределеное значение?
Неизвестный
23.09.2009, 10:50
общий
Alexey Sergeev:
Если же создать поле "Номер коробки" в таблице "Ячейки", то получится, что одна коробка может стоять в нескольких ячейках, что также противоречит условиям задачи.


Тогда могу предложить такое решение: Создать в таблице "Ячейки" поле "Номер коробки" (которая в ней стоит). В таблице "Ячейки" можно также добавить дополнительные атрибуты (кто поставил коробку в ячейку, когда она туда была поставлена и т.д.).

В таблице "Коробки" создать служебное поле "Установ" (по умолчанию = 0; если коробка установлена в какую-либо ячейку, то значение = 1).

Теперь, если какую-либо коробку ставят в ячейку (т.е. номер коробки пытаются ввести в таблицу "Ячейки"), то необходимо проверить поле "Установ" таблицы "Коробки". Если оно не равно 0, то можно вывести сообщение "Эта коробка уже установлена..."

Если коробку изымают из ячейки, то нужно обнулить соответствующее поле "Установ".


Как-то так... Может быть, можно и как-то проще...
Неизвестный
23.09.2009, 18:42
общий
связь один-к-одному между таблицами коробок и ячеек невозможна. т.к. есть возможность наличия нескольких записей в таблице ячеек с нулевым полем коробки ( не занята ) и в таблице коробок с нулевым значением поля ячейки ( никуда не поставлена ) . значение ключа=0 не есть неопределенность. т.к. в таблице такое ключевое значение будет одно, то проблем с уникальностью ключа не возникнет. главное чтобы поле было не "счетчик", а "длинное целое" с уникальным индексом. а отличие содержимого второго поля таблицы от нуля ( код коробка для таблицы ячеек или код ячейки для таблицы коробок ) покажет не только занятость_ячейки/установку_коробка, но и укажет код коробка что был установлен в эту ячейку, либо код ячейки куда был установлен этот коробок.

фактически, в предложенной мной базе нет ни одной связанной таблицы. корректность ввода данных возложена на клиентское приложение или обработчик событий в Access. именно там должно быть предотвращено предоставление занятой ячейки для хранения других коробок ( просто в список выбора включать ячейки с полем коробка = 0 ) .
примерно это выглядит так:
1. поступает партия товара. это отражается в таблице Part. в теории, товар может быть изначально и нераспределен по коробкам
2. распределение товара по коробкам. здесь наверное нужно предлагать только остаток нераспределенных партий товара ( из суммы остатка партии товара, что отражается в таблице Part вычесть сумму распределенного товара этой партии на складе из таблицы Skl ) . Тогда еще нужно будет добавить операцию по извлечению товара из коробок для их дальнейшей реализации или ч-л подобного. можно ограничить распределение товара только по неразмещенным коробкам ( поле ячейки = 0 ) . это будет правильней, как мне кажется.
3. постановка коробка в ячейку ( операция не обязательна ) . здесь сначала нужно проверить отсутствие признака распределения - в таблице Kor поле Yach = 0. также тогда желательно добавить операцию по извлечению коробки из ячейки.
4. извлечение коробки из ячейки.
5. извлечение товара из коробок. данные берутся из таблицы Skl. если коробка пустая, то можно ее сразу вытащить из ячейки ( я не знаю специфику склада, но в теории пустой коробок можно хранить в ячейке ) . если извлечение товара производится только с вынутыми коробками ( поле ячейки = 0 ) , то предлагать для выбора только неустановленные в ячейки коробки. наверное так будет правильнее и логичнее.
6. расход товара со склада - уменьшение остатка партии товара в коробке в таблице Skl с одновременной корректировкой остатка партии в таблице Part.

еще бы желательно точнее описать условия задачи, например:
1. в ячейку может быть установлен коробок, но не обязательно
2. коробок может быть помещен в ячейку, но не обязательно
3. приход партии товара отражается в таблице Part
4. на конец смены весь товар должен быть распределен по коробкам ( возможно, это условие не нужно, но так было бы правильнее для учета и отражения прихода/расхода )
5. партии товара распределяются только в извлеченные из ячеек ( неустановленные в ячейки ) коробки
6. партии товара извлекаются только из извлеченных из ячеек ( неустановленных в ячейки ) коробок
7. расход товара возможен только после извлечения его из коробки
8. коробок с содержимым либо без него может быть помещен в незанятую ячейку в любое время

тогда немного поменяется алгоритм ( с правилами, описанными в предыдущем алгоритме и условиях )
1. приход партии товара
2. распределение товара по неустановленным в ячейки ( вынутым из ячеек ) коробкам
3. извлечение товара из неустановленной в ячейку ( вынутой из ячейки ) коробки ( если извлекается весь остаток партии товара из коробки, то нужно удалить эту запись в таблице Skl )
4. расход товара
дополнительные операции
5. установка коробка ( можно пустого ) в незанятую ячейку
6. извлечение коробки из ячейки


нагородил много. если что непонятно ( надеюсь, это не весь текст ) - пишите в форуме.
Неизвестный
23.09.2009, 18:53
общий
мне проще написать программку на VB6. это пару дней займет. только сейчас завал на работе.
Неизвестный
28.09.2009, 15:46
общий
Гуревич Александр Львович:
Уважаемые эксперты,
Кажется я понял, как связать таблицы отношениями один-к-одному в Access: среди свойств поля есть такое свойство, как "индексировать". Оно допускает следующие значения:
- нет
- да (совпадения не допускаются)
- да (совпадения допускаются).
Так вот, при помощи этого поля можно обеспечить связь один-к-одному между таблицами. Немного искусственно правдо получается, но тем не менее... А вот каким образом на этапе моделирования предметной области БД на схеме сущностей возможно отразить связь один-к-одному между таблицами 'Товары' и 'Коробки' мне так и не понятно ( но если есть возможность это реализовать в БД, то наверное это уже и не важно).
Спасибо за ваши подсказки.
Неизвестный
28.09.2009, 15:46
общий
Филатов Евгений Геннадьевич:
Уважаемые эксперты,
Кажется я понял, как связать таблицы отношениями один-к-одному в Access: среди свойств поля есть такое свойство, как "индексировать". Оно допускает следующие значения:
- нет
- да (совпадения не допускаются)
- да (совпадения допускаются).
Так вот, при помощи этого поля можно обеспечить связь один-к-одному между таблицами. Немного искусственно правдо получается, но тем не менее... А вот каким образом на этапе моделирования предметной области БД на схеме сущностей возможно отразить связь один-к-одному между таблицами 'Товары' и 'Коробки' мне так и не понятно ( но если есть возможность это реализовать в БД, то наверное это уже и не важно).
Спасибо за ваши подсказки.

PS: Повтряю ответ, так как не знаю, как в этом мини форуме ответить сразу нескольким адресатам : )
Форма ответа