Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
17.05.2011, 12:32
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
Уважаемые форумчане! Вопрос у меня вопрос по проектированию базы данных (надеюсь модераторы не отправят топик в "Проектирование БД") :). Есть развёрнутая таблица в 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-варианту, но последний недостаток для меня критичный! Т.е. если пользователь забыл ввести какой-то параметр, то увы, отчёт будет неполноценным. Как быть? Что можете посоветовать? А может есть идея по лучше? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
17.05.2011, 12:48
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
Только 2 вариант. Контроль за вводом данных, можно на клиенте, можно на сервере. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
17.05.2011, 13:10
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
П-ЛТолько 2 вариант. Контроль за вводом данных, можно на клиенте, можно на сервере. Как раз таки проблема в том, чтобы заставить пользователя ввести все 30 параметров. Как это сделать? Желательно на уровне БД. Допустим, пользователь ввел 29, а 1 параметр "прозевал". Допустим, он хочет перейти на новую запись и тут триггер проверит нет ли в подчинённой таблице "неполные" записи. Если есть, то запретит. Вроде бы решение, но только беда. База - многопользовательская, поэтому если кто-то начнёт ввести свои записи, то уже другие не смогут, триггер будет им мешать. Как быть? Надеюсь смог раскрыть суть проблемы. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
17.05.2011, 13:16
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
studierenБаза - многопользовательская, поэтому если кто-то начнёт ввести свои записи, то уже другие не смогут, триггер будет им мешать. Как быть? Надеюсь смог раскрыть суть проблемы. Это только если вы специально потрудитесь с клиента открытую транзакцию в сервере повесить. Я так не делаю. За счет внутренних потрохов форм на клиенте можно решить все вопросы и проблемы с проверками. А на сервере в триггере сделать еще одну проверку - для удовлеторения своей паранойи. Надежность будет полная. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
18.05.2011, 02:33
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
studieren, авторраз в год какой-то столбец убирается, а какой-то добавляется Если верить этому, то можно первый вариант, уж раз в год добавить столбец - не вагон разгрузить, формы, отчёты пересмотреть - один день. Вот если бы хотя бы раз в месяц столбец добавлялся, а так - пустой разговор, на Камазе мешок картошки перевозить. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 20:40
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
Доброе время суток уважаемые форумчане! Сейчас начал разрабатывать новую базу. И тут такая проблема возникла. Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая. Далее, по одному и тому же контракту могут быть 2 и более "Заявок". Значит "Контракты" - главная таблица, а "Заявки" - подчинённая. Но тут маленький нюанс вырисовывается: существуют и такие "Заявки", которые никак не связаны с "Контрактами", т.е. "Заявки" без контрактов. Стало быть поле "Код контракта" можно сделать необязательным. И вот здесь начинается проблема: если "Код контракта" пустой, то тогда получается "Заявка" никак не связана с "Клиентом", а по требованиям бизнес правила таких заявок не должно быть. Каждая заявка должна быть связана с конкретным клиентом. Если в таблицу "Заявки" включить поле "Код клиента", то не очень хорошая схема получается, "Код клиента" и в "Контрактах" и в "Заявках", да и SQL Server не очень "любит" таких схем данных. Как быть? Мне нужны советы (пока не намудрил ещё). Thanks in advance! ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:00
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
А что делать, в реальных задачах часто бывает и несимметрично и не гладко. Можно сделать поле Код Клиента в Заявках и в Контрактах - это не очень большое зло. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:07
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
1. studieren...Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая... False. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:09
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
Смысл используемых с большой буквы терминов (способ их использования и взаимодействия в вашей задаче) понятен только вам. Исходя из того, как одноименные термины могут использоваться "вообще", можно сказать примерно так: Вряд ли у вас получится обойтись без "клиента" в "заявке". Чаще всего "клиент" собственный атрибут "заявки", обязательный к заполнению . Т.е. это связь, идентифицирующая заявку. Относительно того, что по контракту может быть несколько заявок - нужно дать ответ - может ли одна заявка относится к нескольким контрактам. Если да - связь контракт-клиент должна быть представлена отдельной таблицей, представляющей m:n отношение. Если нет - можете оставить ПК "контаркта" прямо в заявке. В таком варианте это связь и обычно и исходя из вашего описания не идентифицирующая . О любви Sql Server к заявкам: это не вопрос любви, а вопрос о том, как мигрирует ПК связанной сущности - для идентифицирующей связи мигрирующий ФК становится частью ПК связанной сущности, для не идентифицирующей - не становится. Если вдруг оказалось так, что клиент часть ПК как контракта, так и заявки И "бизнес-правила" вашей задачи утверждают, связь заявка-контракт 1:n И клиент по заявке и по контракту должен быть один и тот же, то речь идет о слиянии двух мигрировавших в заявку клиетов в одно поле. В противном случае вы допускаете как осмысленную ситуацию, кода Клиент А регистрирует заявку З по контракту, заключенному с клиентом Б. PS Лучше не предполагать, что sql server кого-то любит, тогда все быстрей срастется. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:21
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
опечатка: авторЕсли да - связь контракт-клиент должна быть... читать так: Если да - связь контракт-заявка должна быть... ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:21
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
Программист-Любитель, Ну ведь SQL Server'у такая схема "не нравится", говорит "не хочу" и точка. Как его уговорить? В принципе можно в "Заявках" хоть и добавить поле "Код клиента", но при этом не связывать с таблицей "Клиенты". А вводимый код клиента тогда придётся проверять либо в триггере, либо в Check Constraint (со скалярной функцией). Но почему то такое решение мне не очень нравится. Есть ещё одна идея в "запасе". Может быть мне стоит в таких случаях программно создавать "псевдоконтракты"? Смысл вымышленных контрактов только в том, чтобы обеспечить связь между клиентами и заявками. А в "псевдоконтракты" поставлю какую-то метку о том, что это вовсе не контракт. Может есть идея более "прогрессивнее"? just anotherr tutorОтносительно того, что по контракту может быть несколько заявок - нужно дать ответ - может ли одна заявка относится к нескольким контрактам. Каждый контракт связан с одним конкретным клиентом, тогда как один клиент может заключать много контрактов. Каждая заявка связана либо только с ОДНИМ конкретным контрактом, либо вообще не связана с каким-либо контрактом. Вот во втором случае у меня проблемка. А по одному контракту могут быть множества заявок. Собственно вот такая ситуация. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:31
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
авторВот во втором случае у меня проблемка Извини, я не понимаю существо проблемы. Попробуй описать ее в технических терминах. Вариант: "Я использую суррогатные ключи. В заявке есть поле суррогатного ключа [клиент] (обязательное) и поле суррогатного ключа [контракт] (не обязательное). Бизнес правило требует, чтобы клиент по контакту, в случае когда он указан, был тем же самым, что и клиент по заявке. Я хотел бы чтобы это правило декларативным образом было представлено в схеме данных. Существуют ли такая возможность для субд имярек, отличная от перехода к естественным ключам?" Если бы я затруднялся, я бы что-нибудь такое спрашивал. Попробуйте свой вариант вопроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 21:43
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
исправление: автор... в случае когда он указан... читать так: ... когда поле [контракт] заполнено в заявке... ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 22:05
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
nord-woolf1. studieren...Есть "Клиенты", у которых могут быть 2 и более "Контракта". Стало быть "Клиенты" - главная таблица, "Контракты" - подчинённая... False. Warum? (Я слово "главная" понимаю, как "на стороне 1" в связи "1:N") ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 22:30
|
|||
---|---|---|---|
|
|||
Вопрос по проектированию БД |
|||
#18+
1. Клиент не та компания, которая заключила контракт на стороне Заказчика, а та которая сделала заявку. // Лирика :) 2. Компании - справочник для фактов, например: ... |
|||
:
Нравится:
Не нравится:
|
|||
|
12.10.2011, 22:30
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
В заявках нужны и клиент и контракт. Контракт можно и null, но лучше вводить обязательно. Если нет реального контракта, то виртуальный (в таблице) должен быть. ЗЫ1: У меня еще и четвертой таблицей ком-предложения... ЗЫ2: Сиквел нормально дружит со связями и их отсутствием в случае null ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 06:42
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
Ёжик`Если нет реального контракта, то виртуальный (в таблице) должен быть. +100 Опоздал я маленько, тоже хотел предложить виртуального, ибо пустые записи - это большое зло. Кстати виртуальный может вообще один быть, скажем "anonimus". ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 12:58
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
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 прекрасно дышит в обоих случаях. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 13:50
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
booby, Прочёл несколько раз, но таки нюансы Вашей идеи до конца не понял. Можете в моём примере показать как Вы видите таблицы базы? В реальной базе будет очень много таблиц, но сейчас речь идёт о 3 из них (возможно по Вашей схеме их будет и больше). Итак. Вот примерно так я себе представляю эти таблицы КлиентыКод клиентаКлиентАдресКонтактное лицоДолжностьТелефони другие поля КонтрактыКод контрактаНомерДатаВалютаСуммаКод клиентаи другие поля ЗаявкиКод заявкиНомерДатаКод контрактаВалютаСумма P.S. не обращайте внимание на пробелы в названиях полей таблиц, в реальной таблице конечно же я их уберу. :) К тому же я предпочитаю английские названия. :) Т.е. насколько я понял Вы предлагаете вообще отказаться от "псевдоконтракт"? Интересно. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 14:54
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
studieren, попробую перевести :) вариант 1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
'Выбирай, но осторожно. Осторожно, но выбирай.' :) Оба варианта рабочие. В конкретном случае я бы выбрал №2 :) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 15:17
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
adv, Понял. :) Спасибо всем!!! ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 15:19
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
2 adv Как лихо вы скрещиваете ежа с бакланом. Ваш вариант 1 – это предложение Ёжика, с требованием ввода фиктивных котрактов. Мое скромное мнение – это не рабочий вариант имеено в силу требования фейковых записей в таблицах и дополнительно запрограммированной логики по обращению с ними. Я ясно и однозначно высказал свое отношение к этому варианту. Ваше вариант 2 – это не добуквенное воспроизведение того, что предлагал я как вариант А). Добуквенно это будет так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 15:25
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
2 adv приношу извинения. это я лихо и криво прочитал вашу запись. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
13.10.2011, 15:37
|
|||
---|---|---|---|
Вопрос по проектированию БД |
|||
#18+
кстати, и свою нарисовал, в итоге, с ошибкой... ... |
|||
:
Нравится:
Не нравится:
|
|||
|
|
start [/forum/topic.php?fid=45&mobile=1&tid=1614053]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
71ms |
get tp. blocked users: |
1ms |
others: | 315ms |
total: | 475ms |
0 / 0 |