powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Вопрос по проектированию БД
25 сообщений из 34, страница 1 из 2
Вопрос по проектированию БД
    #37264425
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые форумчане!
Вопрос у меня вопрос по проектированию базы данных (надеюсь модераторы не отправят топик в "Проектирование БД") :).

Есть развёрнутая таблица в Excel, где-то порядка 30 столбцов, из которых:
1-столбец - дата,
2-4-столбцы - текст
5-30-столбцы - число.
Структура таблицы (отчёта) не строго зафиксирована, раз в год какой-то столбец убирается, а какой-то добавляется, при этом число столбцов тоже может поменяться!
Но при этом первые 4 столбца никогда не меняются.

Мне нужно создать БД и перевести данные из Excel в Access/SQL Server.
У меня 2 варианта:
1) создаю точную копию таблицы с 30 полями
2) разбиваю на 2 таблицы примерно так:
- ГлавнаяТаблица (ID, Date, Text1, Text2, Text3) - названия полей условные
- ПодчинённаяТаблица (ID, Parameter, Value) - здесь "Parameter" как бы название столбца из исходного Excel файла

У каждого из этих вариантов есть как "+" так и "-".
Преимущества 1-варианта:
- практически все отчёты развёрнутые, поэтому простым SELECTом отчёты будут формироваться элементарно.
- всех числовых полей можно сделать обязательными.
Недостатки 1-варианта:
- если нужно сворачивать, а не развернуть отчёт (т.е. в SQL Server - PIVOT, а в Access - UNION), то получается довольно громоздкая конструкция (особенно в Access). Из-за этого запрос будет работать медленнее (правда таких отчётов очень и очень мало).
- самый главный недостаток: после изменения бизнес правил, когда нужно добавить или удалить столбец, увы, придётся структуру таблицы менять, также пересмотреть все отчёты.

Преимущества 2-варианта:
- для "добавления" или "удаления" столбца совсем не требуется изменение структуры таблицы, достаточно ввести новый параметр.
- суммирование и группировка данных достаточно просто.
Недостатки 2-варианта:
- для развёрнутого отчёта постоянно придётся использовать PIVOT. В принципе отчёты всегда фильтруются, поэтому данный недостаток не критичный, не существенный.
- нет возможности (по крайнем мере я не знаю как) сделать обязательным некоторые параметры. Т.е. когда таблица развёрнута, то все числовые поля можно сделать обязательными, а когда свернули как же на уровне БД все параметры сделать обязательными?

Сам я больше склоняюсь ко 2-варианту, но последний недостаток для меня критичный! Т.е. если пользователь забыл ввести какой-то параметр, то увы, отчёт будет неполноценным. Как быть? Что можете посоветовать? А может есть идея по лучше?
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37264474
П-Л
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только 2 вариант.

Контроль за вводом данных, можно на клиенте, можно на сервере.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37264539
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
П-ЛТолько 2 вариант.

Контроль за вводом данных, можно на клиенте, можно на сервере.

Как раз таки проблема в том, чтобы заставить пользователя ввести все 30 параметров. Как это сделать? Желательно на уровне БД.
Допустим, пользователь ввел 29, а 1 параметр "прозевал". Допустим, он хочет перейти на новую запись и тут триггер проверит нет ли в подчинённой таблице "неполные" записи. Если есть, то запретит. Вроде бы решение, но только беда. База - многопользовательская, поэтому если кто-то начнёт ввести свои записи, то уже другие не смогут, триггер будет им мешать. Как быть?

Надеюсь смог раскрыть суть проблемы.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37264554
П-Л
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenБаза - многопользовательская, поэтому если кто-то начнёт ввести свои записи, то уже другие не смогут, триггер будет им мешать. Как быть?
Надеюсь смог раскрыть суть проблемы.
Это только если вы специально потрудитесь с клиента открытую транзакцию в сервере повесить. Я так не делаю.
За счет внутренних потрохов форм на клиенте можно решить все вопросы и проблемы с проверками. А на сервере в триггере сделать еще одну проверку - для удовлеторения своей паранойи. Надежность будет полная.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37266174
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

авторраз в год какой-то столбец убирается, а какой-то добавляется

Если верить этому, то можно первый вариант, уж раз в год добавить столбец - не вагон разгрузить, формы, отчёты пересмотреть - один день. Вот если бы хотя бы раз в месяц столбец добавлялся, а так - пустой разговор, на Камазе мешок картошки перевозить.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479529
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброе время суток уважаемые форумчане!

Сейчас начал разрабатывать новую базу. И тут такая проблема возникла.
Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая.
Далее, по одному и тому же контракту могут быть 2 и более "Заявок". Значит "Контракты" - главная таблица, а "Заявки" - подчинённая.
Но тут маленький нюанс вырисовывается: существуют и такие "Заявки", которые никак не связаны с "Контрактами", т.е. "Заявки" без контрактов. Стало быть поле "Код контракта" можно сделать необязательным. И вот здесь начинается проблема: если "Код контракта" пустой, то тогда получается "Заявка" никак не связана с "Клиентом", а по требованиям бизнес правила таких заявок не должно быть. Каждая заявка должна быть связана с конкретным клиентом. Если в таблицу "Заявки" включить поле "Код клиента", то не очень хорошая схема получается, "Код клиента" и в "Контрактах" и в "Заявках", да и SQL Server не очень "любит" таких схем данных.
Как быть?
Мне нужны советы (пока не намудрил ещё).

Thanks in advance!
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479557
Фотография Программист-Любитель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что делать, в реальных задачах часто бывает и несимметрично и не гладко. Можно сделать поле Код Клиента в Заявках и в Контрактах - это не очень большое зло.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479567
Фотография nord-woolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.
studieren...Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая...
False.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479571
just anotherr tutor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Смысл используемых с большой буквы терминов (способ их использования и взаимодействия в вашей задаче) понятен только вам.
Исходя из того, как одноименные термины могут использоваться "вообще", можно сказать примерно так:

Вряд ли у вас получится обойтись без "клиента" в "заявке". Чаще всего "клиент" собственный атрибут "заявки", обязательный к заполнению . Т.е. это связь, идентифицирующая заявку.

Относительно того, что по контракту может быть несколько заявок - нужно дать ответ - может ли одна заявка относится к нескольким контрактам.
Если да - связь контракт-клиент должна быть представлена отдельной таблицей, представляющей m:n отношение.
Если нет - можете оставить ПК "контаркта" прямо в заявке. В таком варианте это связь и обычно и исходя из вашего описания не идентифицирующая .

О любви Sql Server к заявкам: это не вопрос любви, а вопрос о том, как мигрирует ПК связанной сущности - для идентифицирующей связи мигрирующий ФК становится частью ПК связанной сущности, для не идентифицирующей - не становится.
Если вдруг оказалось так, что клиент часть ПК как контракта, так и заявки И "бизнес-правила" вашей задачи утверждают, связь заявка-контракт 1:n И клиент по заявке и по контракту должен быть один и тот же, то речь идет о слиянии двух мигрировавших в заявку клиетов в одно поле.
В противном случае вы допускаете как осмысленную ситуацию, кода Клиент А регистрирует заявку З по контракту, заключенному с клиентом Б.


PS
Лучше не предполагать, что sql server кого-то любит, тогда все быстрей срастется.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479584
just another tutor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
опечатка:
авторЕсли да - связь контракт-клиент должна быть...
читать так:
Если да - связь контракт-заявка должна быть...
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479585
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист-Любитель,

Ну ведь SQL Server'у такая схема "не нравится", говорит "не хочу" и точка. Как его уговорить?
В принципе можно в "Заявках" хоть и добавить поле "Код клиента", но при этом не связывать с таблицей "Клиенты". А вводимый код клиента тогда придётся проверять либо в триггере, либо в Check Constraint (со скалярной функцией). Но почему то такое решение мне не очень нравится.

Есть ещё одна идея в "запасе". Может быть мне стоит в таких случаях программно создавать "псевдоконтракты"? Смысл вымышленных контрактов только в том, чтобы обеспечить связь между клиентами и заявками. А в "псевдоконтракты" поставлю какую-то метку о том, что это вовсе не контракт.

Может есть идея более "прогрессивнее"?

just anotherr tutorОтносительно того, что по контракту может быть несколько заявок - нужно дать ответ - может ли одна заявка относится к нескольким контрактам.
Каждый контракт связан с одним конкретным клиентом, тогда как один клиент может заключать много контрактов.
Каждая заявка связана либо только с ОДНИМ конкретным контрактом, либо вообще не связана с каким-либо контрактом. Вот во втором случае у меня проблемка. А по одному контракту могут быть множества заявок.

Собственно вот такая ситуация.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479603
just another tutor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторВот во втором случае у меня проблемка
Извини, я не понимаю существо проблемы.
Попробуй описать ее в технических терминах.
Вариант:
"Я использую суррогатные ключи. В заявке есть поле суррогатного ключа [клиент] (обязательное) и поле суррогатного ключа
[контракт] (не обязательное). Бизнес правило требует, чтобы клиент по контакту, в случае когда он указан, был тем же самым, что и клиент по заявке.
Я хотел бы чтобы это правило декларативным образом было представлено в схеме данных. Существуют ли такая возможность для субд имярек, отличная от перехода к естественным ключам?"

Если бы я затруднялся, я бы что-нибудь такое спрашивал.
Попробуйте свой вариант вопроса.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479611
исправление:
автор... в случае когда он указан...
читать так:
... когда поле [контракт] заполнено в заявке...
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479636
Фотография Sator Arepo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nord-woolf1.
studieren...Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая...
False.
Warum? (Я слово "главная" понимаю, как "на стороне 1" в связи "1:N")
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479661
Фотография nord-woolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Клиент не та компания, которая заключила контракт на стороне Заказчика, а та которая сделала заявку. // Лирика :)
2. Компании - справочник для фактов, например:
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479662
Фотография Ёжик`
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В заявках нужны и клиент и контракт.
Контракт можно и null, но лучше вводить обязательно.
Если нет реального контракта, то виртуальный (в таблице) должен быть.

ЗЫ1: У меня еще и четвертой таблицей ком-предложения...
ЗЫ2: Сиквел нормально дружит со связями и их отсутствием в случае null
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37479826
alvk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик`Если нет реального контракта, то виртуальный (в таблице) должен быть.



+100

Опоздал я маленько, тоже хотел предложить виртуального, ибо пустые записи - это большое зло. Кстати виртуальный может вообще один быть, скажем "anonimus".
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480518
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alvkЁжик`Если нет реального контракта, то виртуальный (в таблице) должен быть.



+100

Опоздал я маленько, тоже хотел предложить виртуального, ибо пустые записи - это большое зло. Кстати виртуальный может вообще один быть, скажем "anonimus".

-100
Studieren, не верь никому.
Утверждение о вредности Null восходит к Дейту.
Он единственный, кто пытается под это подложить хоть какую-то логику.
Однако, следует иметь в виду, что в своих рассуждениях Дейт располагается в рамках
реляционной модели данных, в которой отсутствует прямая операция вида Outer Join.
Outer Join у реляционистов – операция производная, выводимая не вполне тривиальным образом, поэтому outer join – это последнее, о чем думает реляционист.

Отступление:
Спроси любого, изучавшего математику – что такое ноль и зачем он нужен.
Единственный вменяемый ответ, который ты получишь, будет таким – ноль эта такая хреновина, которая нужна для того, чтобы математика сходилась. Ну, чтобы операция вычитания, например, оказалась определена на всем множестве целых чисел.
А в ответ на вопрос, сколько нужно числовых нулей математике, (ведь в ней много разных числовых множеств с несовпадающими свойствами), ты получишь такой ответ – пока одним обходимся.

Возврат:
Посмотри на ситуацию с этой стороны. SQL обходится одним единственным нулем для обозначения пропущенных по любой причине значений. Пропуск значения универсально обозначает не только неполноту данных, но и незавершенность процесса, например.
Радетелям за реляционную чистоту и продвигателям реляционных идей в массы приходится а) заводить столько несовпадающих нулей, сколько типов данных они используют в своих системах и б) кроме нулевых значений вводить еще нулевые сущности (см. два предыдущих поста), там, где речь идет о пропущенных или отсутствующих связях в ситуации 0-n:0-m – и приговаривать, что это очень хорошо.

Ближе к телу:
Для принятия решения о том, как поступить, ты должен 1) дать себе отчет, какую роль играет тот илиной реквизит в заявке – роль собственного реквизита заявки или роль атрибута, связывающего заявку с другими сущностями, и 2) посмотреть на ситуацию с точки зрения того, что дожно измениться в схеме либо при изменении бизнес-правил.
(например, ты хотел бы применять свои наработки в похожих, но не полностью совпадающих ситуациях).
1) Принципиальный момент здесь вот в чем. Атрибуты, выполняющие только роль связующих между сущностями, с точки зрения реляционной чистоты модели, должны быть выделены в собственные сущности, т.к. связи между сущностями в реляционной модели представляются самостоятельными сущностями ( таблицами, в терминологии sql).
Сейчас описанная тобой ситуация выглядит так. роль клиента в заявке – двойная.
[клиент] в Заявке не просто связывает Клиента и Заявку в отношении 1:0-n, но представляет собой неотемлемый собственный атрибут Заявки пропуск которого недопустим, т.к. без него идетификация Заявки недостаточна, чтобы быть размещенной в таблицу в виде строки.
Попутный вопрос о нулях для размышления.
Пусть мы ошибочно решили, что связь между Клиентом и заякой 1:N, а не 1:0-N и сейчас находимся на этапе заведения нового клиента. Должны ли мы при добавлении
нового клиента завести на него одновременно и фиктивную заявку, которую он еще не подавал. Ответ – должны. Нулей (фиктивных заявок), чтобы наша математика 1:N сходилась, здесь будет столько, сколько клиентов заведено в базе (хихикать разрешается).

Роль же атрибута [контракт] – только связующая. [контракт] не является собственным атрибутом заявки, выражает связь между Контрактами и Заявками и поэтому с самого начала должен быть размещен в соственную таблицу, представляющую связь между Контрактами и Заявками.
А) Однако, т.к. согласно анализу предмета, связь со стороны Контракта 1, а со стороны Заявки 0-n, принимается решение денормализовать базу и разместить атрибут [контракт] прямо в сущности Заявка, допустив, естественным образом, наличие null-значений для этого атрибута.
Б) Альтернативой могло бы быть создание сущности Связь_Заявка_Контракт, с миграцией первичного ключа Заявки в эту сущность в качестве первичного ключа вновь образованной сущности. Таким образом, отношение между Заявкой и Связь_Заявка_Контракт оказалось бы 1:0-1, что позволило бы поддержать отношение 1:0-n между Заявкой и Контрактом с помошью Связь_Заявка_Контракт.

2) Допустим, вы хотите понять, что нужно изменить в получившихся двух вариантах реализации для ситуации, когда связь между Заявкой и Контрактом превращается из 1:0-N в N:0-M. В варианте А) необходимо произвести следующие действия
- создать таблицу Связь_Заявка_Контракт, заявив в ней оба поля [заявка] и [контракт] как not null и декларировав соотетствующие ФК.
- импортировать в нее из Заявка данные по накопленным связям.
- удалить атрибут [контракт] из Заявки.
В варианте Б) таблица связи уже есть, нужно
- дополнить первичный ключь Связь_Заявка_Контракт до возможности поддержки N:0-M, например, мигрировав в него атрибут [контракт]. Других действий не требуется.
Обращаю ваше внимание, что развитие системы в обоих сценариях идет без создания искусственных нулей не только на типах данных, но, и, тем более, без заведения искусственных нулевых экземпляров сущностей.
Outer Join прекрасно дышит в обоих случаях.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480635
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

Прочёл несколько раз, но таки нюансы Вашей идеи до конца не понял. Можете в моём примере показать как Вы видите таблицы базы?
В реальной базе будет очень много таблиц, но сейчас речь идёт о 3 из них (возможно по Вашей схеме их будет и больше).
Итак. Вот примерно так я себе представляю эти таблицы
КлиентыКод клиентаКлиентАдресКонтактное лицоДолжностьТелефони другие поля

КонтрактыКод контрактаНомерДатаВалютаСуммаКод клиентаи другие поля

ЗаявкиКод заявкиНомерДатаКод контрактаВалютаСумма
P.S. не обращайте внимание на пробелы в названиях полей таблиц, в реальной таблице конечно же я их уберу. :) К тому же я предпочитаю английские названия. :)

Т.е. насколько я понял Вы предлагаете вообще отказаться от "псевдоконтракт"?
Интересно. :)
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480823
Фотография adv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studieren,

попробую перевести :)

вариант 1
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create table Client1 (ClientID int not null primary key);

create table Contract1 (
ContractID int not null primary key,
ClientID int not null,
foreign key (ClientID) references  Client1 (ClientID)
);

create table Order1 (
OrderID int not null primary key,
ClientID int not null,
foreign key (ClientID) references  Client1 (ClientID)
);

create table OrderContract1 (
OrderID int not null primary key,
ContractID int not null,
foreign key (OrderID) references  Order1 (OrderID),
foreign key (ContractID) references  Contract1 (ContractID)
);
вариант 2
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table Client2 (ClientID int not null primary key);

create table Contract2 (
ContractID int not null primary key,
ClientID int not null,
foreign key (ClientID) references  Client2 (ClientID)
);

create table Order2 (
OrderID int not null primary key,
ClientID int not null,
ContractID int null,
foreign key (ClientID) references  Client2 (ClientID),
foreign key (ContractID) references  Contract2 (ContractID)
);

'Выбирай, но осторожно. Осторожно, но выбирай.' :)

Оба варианта рабочие.

В конкретном случае я бы выбрал №2 :)
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480893
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adv,

Понял. :)
Спасибо всем!!!
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480897
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 adv

Как лихо вы скрещиваете ежа с бакланом.
Ваш вариант 1 – это предложение Ёжика, с требованием ввода фиктивных котрактов.
Мое скромное мнение – это не рабочий вариант имеено в силу требования фейковых записей в таблицах и дополнительно запрограммированной логики по обращению с ними.
Я ясно и однозначно высказал свое отношение к этому варианту.

Ваше вариант 2 – это не добуквенное воспроизведение того, что предлагал я как вариант А).
Добуквенно это будет так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create table Client2 (ClientID int not null primary key);

create table Contract2 (
ContractID int not null,
ClientID int not null,
);
Alter Table Contract2 Add Constraint PK_Contract Primary Key (contractID,ClientID) using index;
Alter Table Contract2 Add Constraint FK_Contract_Client Foreign Key (ClientID) References Client2 (ClientID) using index; --  on delete cascade маловероятен, - restrict 

Create Table ClientRequest(
   RequestID int not null,
   ClientID  int not null,
   contractID int null
)
Alter Table ClientRequest Add Constraint PK_Request Primary Key
(requestID, ClientID) using index;
Alter Table ClientRequest Add Constraint FK_request_Client Foreign Key
(ClientID) References Client2(Client2) On Delete Cascade using Index;
Alter Table ClientRequest Add Constraint FK_request_Contract Foreign Key
(contractID) references Contract (contractID) on Delete Set Null using index;
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480917
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 adv
приношу извинения.
это я лихо и криво прочитал вашу запись.
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37480955
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, и свою нарисовал, в итоге, с ошибкой...
...
Рейтинг: 0 / 0
Вопрос по проектированию БД
    #37481162
Осьменоги
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
boobyкстати, и свою нарисовал, в итоге, с ошибкой...
зато многа! да!
...
Рейтинг: 0 / 0
25 сообщений из 34, страница 1 из 2
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Вопрос по проектированию БД
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]