Первый раз проектирование базы данных: я перерабатываю?

233

Фон

Я студент CS первого курса, и я работаю неполный рабочий день для своего малыша. У меня нет опыта разработки приложений в реальном мире. Я написал сценарии на Python, некоторые курсовые работы на C, но ничего подобного.

У моего папы небольшой учебный бизнес, и в настоящее время все классы запланированы, записаны и обработаны через внешнее веб-приложение. Существует функция экспорта/ "отчетов", но она очень общая, и нам нужны конкретные отчеты. У нас нет доступа к фактической базе данных для запуска запросов. Меня попросили создать настраиваемую систему отчетности.

Моя идея состоит в том, чтобы создавать общий CSV-экспорт и импорт (возможно, с Python) их в базу данных MySQL, размещенную в офисе каждую ночь, откуда я могу запускать конкретные запросы, которые необходимы. У меня нет опыта работы с базами данных, но я понимаю самые основы. Я немного читал о создании базы данных и нормальных формах.

Мы можем начать с международных клиентов в ближайшее время, поэтому я хочу, чтобы база данных не взрывалась, если/когда это произойдет. У нас также есть несколько крупных корпораций в качестве клиентов, с различными подразделениями (например, материнская компания ACME, подразделение здравоохранения ACME, подразделение ACME bodycare)

Я привел следующую схему:

  • С точки зрения клиента:
    • Клиенты являются основной таблицей
    • Клиенты связаны с отделом, в котором они работают
      • Отделы могут быть разбросаны по всей стране: HR в Лондоне, маркетинг в Суонси и т.д.
      • Отделы связаны с подразделением компании.
    • Подразделения связаны с материнской компанией.
  • С точки зрения классов:
    • Сессии - это основная таблица
      • Учитель связан с каждым сеансом.
      • Каждому сеансу присваивается статус. Например. 0 - Завершено, 1 - Отменено
      • Сессии группируются в "пакеты" произвольного размера
    • Каждый пакет присваивается клиенту

Я "спроектировал" (более похоже на нацарапанную) схему на листе бумаги, пытаясь сохранить нормализацию к третьей форме. Затем я подключил его к MySQL Workbench, и он сделал все для меня довольно приятным:
(Нажмите здесь для полноразмерной графики)

alt text http://maian.org/img/schema.png

Пример запросов Я буду запускать

  • Какие клиенты с остатком кредита остаются бездействующими (те, у кого нет класса, запланированного в будущем)
  • Каков уровень посещаемости для каждого клиента/отдела/подразделения (измеряется идентификатором статуса в каждом сеансе).
  • Сколько классов имеет учитель в месяц
  • Клиенты флагов, у которых низкая посещаемость.
  • Пользовательские отчеты для отделов кадров с посещаемостью людей в их подразделении

Вопрос (ы)

  • Является ли это слишком сложным, или я правильно направился?
  • Будет ли необходимость объединения нескольких таблиц для большинства запросов, приведет к большому результату?
  • Я добавил для клиентов столбец "lastsession", поскольку, вероятно, это будет общий запрос. Является ли это хорошей идеей или я должен строго поддерживать нормализацию базы данных?

Спасибо за ваше время

  • 128
    Уважаемый студент CS первого курса: продолжайте использовать StackOverflow. Ваш вопрос интересен, хорошо написан и полезен. Другими словами, вы находитесь в топе 1% респондентов.
  • 0
    Может ли Дивизион содержать другие Дивизии? ЕСЛИ в этом случае таблица «имеет» может быть использована для связи Отдела с Отделом, в котором он содержится.
Показать ещё 6 комментариев
Теги:
database
schema
database-design
database-normalization

12 ответов

37
Лучший ответ

Еще несколько ответов на ваши вопросы:

1) Вы в значительной степени нацелены на кого-то, кто впервые сталкивается с такой проблемой. Я думаю, что указатели от других по этому вопросу до сих пор в значительной степени охватывают его. Хорошая работа!

2 и 3). Эффективность, которую вы получите, будет во многом зависеть от наличия и оптимизации правильных индексов для ваших конкретных запросов/процедур и, что более важно, объема записей. Если вы не говорите о более чем миллионах записей в ваших основных таблицах, вы, похоже, на пути к тому, чтобы иметь достаточно основной дизайн, что производительность не будет проблемой на разумном оборудовании.

Тем не менее, это относится к вашему вопросу 3, но с самого начала вы, вероятно, не должны чрезмерно беспокоиться о производительности или гиперчувствительности к нормализации православия здесь. Это сервер отчетов, который вы создаете, а не бэкэнд приложения на основе транзакций, который будет иметь совершенно другой профиль в отношении важности производительности или нормализации. База данных, поддерживающая приложение регистрации и планирования в реальном времени, должна учитывать запросы, требующие секунд для возврата данных. Мало того, что функция сервера отчетов имеет больше терпимости к сложным и длительным запросам, но стратегии повышения производительности сильно различаются.

Например, в среде приложений на основе транзакций ваши параметры улучшения производительности могут включать рефакторинг ваших хранимых процедур и структур таблиц в n-й степени или разработку стратегии кэширования для небольших объемов обычно запрашиваемых данных. В среде отчетности вы, безусловно, можете это сделать, но вы можете иметь еще большее влияние на производительность, внедряя механизм моментальных снимков, в котором запускается запланированный процесс, и сохраняет предварительно сконфигурированные отчеты, а ваши пользователи получают доступ к данным моментальных снимков без стресса на вашем уровне db на за каждый запрос.

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

  • 1
    1. Спасибо, это обнадеживает! 2 и 3. Я до сих пор не знаю, как работают индексы, это то, о чем я планировал прочитать. Если у нас когда-нибудь возникнет «проблема» в достижении миллиона записей, вероятно, будет бюджет, чтобы нанять опытных разработчиков: P Спасибо за понимание различных существующих ролей БД, для меня это все ново и очень интересно знать. Я посмотрю на снимки, потому что то, что вы описываете, является в основном конечной целью проекта.
  • 0
    Если вы понимаете таблицы, основы индексов довольно просты. Концептуально, индекс может быть (и часто это) реализован в виде таблицы с очень небольшим количеством столбцов, содержимое которых скопировано из основной таблицы, и ссылкой на основную таблицу, строки которой отсортированы по кеоту для быстрого доступа. Дерево B + является наиболее распространенным механизмом индексации, но при оптимизации индексов крупные игроки используют свои дифференцирующие технологии, поэтому становится неясным, если вы попытаетесь применить аналогию слишком глубоко.
14

У тебя есть правильная идея. Вы можете очистить его и удалить некоторые таблицы отображения (есть *).

Что вы можете сделать в таблице отделов, добавьте CityId и DivisionId.

Кроме того, я думаю, все в порядке...

  • 4
    Я думаю, что ему нужны таблицы сопоставления, если он хочет повторно использовать определение отдела в разных отделах или городах.
  • 1
    Да, я согласен ..... но это звучало так, будто департамент мог находиться только в одном городе / округе. Если нет, то то, что он имел, было определенно правильно.
Показать ещё 1 комментарий
6

Единственные изменения, которые я внес бы:
1- Измените свой VARCHAR на NVARCHAR, если вы собираетесь переходить на международный уровень, вам может понадобиться unicode.

2 Если возможно, измените свой идентификатор int на GUID (uniqueidentifier) ​​(это может быть только мое личное предпочтение). Предполагая, что вы в конечном итоге дойдете до точки, где у вас несколько сред (dev/test/staging/prod), вы можете перенести данные с одного на другой. Идентификаторы GUID делают это значительно проще.

3- Три слоя для вашей компании → Отдел → Структура отдела может быть недостаточной. Теперь это может быть чрезмерное проектирование, но вы можете обобщить эту иерархию, чтобы вы могли поддерживать n-уровни глубины. Это сделает некоторые из ваших запросов более сложными, так что это может не стоить компромисса. Кроме того, может быть, что любой клиент, у которого есть больше слоев, может быть легко "сложенным" в эту модель.

4- У вас также есть статус в таблице клиентов, который является VARCHAR и не имеет ссылки на таблицу статусов. Я ожидал бы немного большей ясности в отношении того, что представляет собой статус клиента.

  • 0
    1- Спасибо, у меня были проблемы с диакритическими знаками и UTF8, для которых я собирался опубликовать еще один вопрос. Может быть, это проблема. 2- Я читал здесь некоторые другие вопросы о SO с большим количеством противоречивых мнений по этому вопросу, я буду больше читать по этому вопросу. 3. Я еще раз расскажу об этом со своим отцом, посмотрев «спецификации», которые я написал, и посмотрим, стоит ли нам на это смотреть. - Не мог бы следующий комментарий
  • 0
    4- Я не стал вдаваться в основной вопрос для краткости: статус на клиенте - активны ли они (есть ли сеансы остаются) или неактивны (не осталось ни одной сессии). Под большей ясностью вы имеете в виду более описательное название col? Например, enrolment_status? Спасибо за ваш вклад.
Показать ещё 7 комментариев
5

Кстати, стоит отметить, что если вы уже генерируете CSV и хотите загрузить их в базу данных mySQL, LOAD DATA LOCAL INFILE - ваш лучший друг: http://dev.mysql.com/doc/refman/5.1/en/load-data.html. Mysqlimport также стоит изучить, и это инструмент командной строки, который в основном представляет собой красивую обертку с информацией о загрузке данных.

5

Нет. Похоже, вы разрабатываете на хорошем уровне детализации.

Я думаю, что страны и компании действительно являются одним и тем же объектом в вашем дизайне, а также городами и отделами. Я бы избавился от таблиц "Страны и города" (и Cities_Has_Departments) и, при необходимости, добавил логический флаг IsPublicSector в таблицу компаний (или столбец CompanyType, если есть больше вариантов, чем просто частный сектор/государственный сектор).

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

Другими словами, клиенты должны быть привязаны к таблице, которую вы называете Divisions_Has_Departments (но я бы назвал просто департаменты). Если это так, то вы должны свернуть города в разделы, как обсуждалось выше, если вы хотите использовать стандартную ссылочную целостность в базе данных.

  • 0
    Таблица стран предназначена для того, если / когда у нас есть клиенты, которые работают более чем в одной стране и имеют разные отделы кадров для каждой из них. Таким образом, мы можем создавать отчеты с данными из страны, в которой работает департамент. То же самое для департаментов и городов, я думаю, у нас есть клиент, у которого есть отдельные отделы кадров. для двух городов, в которых у них есть главные офисы. Или, по крайней мере, такова была причина, я сижу и переосмысливаю это, чтобы увидеть, действительно ли они необходимы. Если бы не думал о CompanyType, я выясню, нужно ли это отслеживать.
  • 0
    RE: таблица depts, моя первоначальная идея заключалась в том, чтобы использовать ее в качестве фактических отделов, указав тип отдела. Мне не приходило в голову просто иметь типы отделов, что кажется более логичным. Зная, к какому отделу и где принадлежит кто-то, я подумал, что если бы отдел был связан с городом и отделом (который связан с компанией), это сработало бы. Был ли я не прав? Для разделения городов на подразделения некоторые подразделения охватывают несколько городов, и я думаю, что, возможно, даже страны. Я посмотрю на это снова. Спасибо за ваш вклад.
3

Следующие комментарии основаны на роли специалиста по бизнес-аналитике/отчетности и менеджера по стратегии/планированию:

  • Я согласен с Ларри выше. ИМХО, это не так много над инженерами, некоторые вещи просто выглядят немного неуместными. Чтобы это было просто, я бы поместил клиента непосредственно на идентификатор компании, описание отдела, описание раздела, идентификатор типа отдела, идентификатор типа подразделения. Использовать идентификатор типа отдела и идентификатор типа подразделения в качестве ссылок на таблицы поиска и внутренние поля отчетов/анализа для долгосрочной согласованности.

  • В таблице Packs содержится столбец "Кредит", не должен ли быть привязан к базовой таблице клиента, поэтому, если у вас много пакетов, вы можете увидеть, сколько кредитов осталось для будущих классов? Приложение может позаботиться о вычислении и сохранить его централизованно в таблице Client.

  • Информация о компании может использовать еще много полей, включая очевидный адрес/телефон/и т.д. Информация. Я также был бы готов добавить в D & B "DUNs" колонки (Site/Branch/Ultimate) в долгосрочной перспективе, Dun и Bradstreet (D & B) имеют огромный каталог компаний, и вы позже увидите их информация очень полезна для отчетности/анализа. Это позаботится о проблеме с множественным разделением, которую вы упомянули, и позволит вам свертывать свою иерархию для суб/деления/веток/и т.д. больших корпусов.

  • Вы не указываете, сколько записей вы будете работать, и это может означать, что вы должны создать большую инициативу развития, которая могла бы быть сделана быстрее и намного меньше головных болей с предварительно упакованным программным обеспечением "отчетности". Если вы не имеете дело с большими базами данных (< 65000), убедитесь, что MS-Access, OpenOffice (Base) или связанные с ними решения для отчетов и приложений не могут сделать трюк. Я использую Oracle бесплатное программное обеспечение APEX совсем немного, оно поставляется со своей бесплатной базой данных Oracle XE, просто загружайте его со своего сайта.

  • FYI - представление отчетов: для больших баз данных обычно есть два экземпляра базы данных: a) база данных транзакций для записи каждой подробной записи. б) отчетная база данных (хранилище данных/хранилище данных), размещенная на отдельной машине. Для получения дополнительной информации найдите google как Star Schema, так и Snowflake Schema.

С уважением.

  • 0
    1. Вы имеете в виду добавление всех этих столбцов в таблицу клиента? Я думаю, что это нарушило бы нормализацию, а также затруднило бы постоянство, хотя я не уверен, что правильно понял. 2. Пакеты являются последовательными, кредит может иметь только последний пакет, поэтому нет необходимости отслеживать несколько пакетов. Вы все еще порекомендуете сохранить его в таблице клиента в этом случае? 3. Похоже, будет очень полезно выяснить структуру компаний-клиентов, я посмотрю на это, спасибо.
  • 0
    4. Мне нужно будет проверить количество клиентов и сессий, которые мы ожидаем в следующем году, но мне кажется возможным, чтобы таблица сессий достигла такого количества строк в год или около того. Я посмотрю на программное обеспечение для отчетности, мне не пришло в голову. 5. Кажется, что я попал в такую ситуацию случайно; веб-приложение будет нашей «базой данных транзакций», а этот проект - нашей «базой данных репотирования» :) Спасибо за ваш вклад.
Показать ещё 2 комментария
3

Большинство вещей уже было сказано, но я чувствую, что могу добавить одно: для более молодых разработчиков довольно часто приходится беспокоиться о производительности немного вперед, и ваш вопрос о соединении таблиц, похоже, входит в это направление. Это анти-шаблон разработки программного обеспечения, называемый Преждевременная оптимизация. Попытайтесь изгнать этот рефлекс из своего разума:)

Еще одно: считаете ли вы, что вам действительно нужны таблицы "городов" и "стран"? Не хватит ли столбца "город" и "страна" в таблице отделов для ваших случаев использования? Например. требуется ли ваше приложение для отображения отделов по городам и городам по странам?

  • 1
    Как я ни старался , он продолжает брать ove, вычисляет большую O из helloworld.c, оптимизирует Таблицы городов и стран просто порождались, когда я следовал инструкциям, чтобы получить базу данных 3NF. Я предполагаю, что преимущество, которое они предлагают, состоит в согласованности названий городов / стран. Например, если мы получим клиента в Мюнхене, и по какой-то причине, кто бы ни вводит нового студента в систему планирования, он решит назвать его Мюнхеном, а не Мюнхеном, как для предыдущих студентов. Также нам может понадобиться перечислить отделы по городам, я должен проверить. Благодарю.
  • 2
    Оптимизация на этапе проектирования базы данных имеет решающее значение! Оптимизация не является преждевременной, так как базы данных значительно сложнее перефразировать, когда они имеют миллион записей.
Показать ещё 1 комментарий
2

Я хочу обратить внимание только на то, что присоединение к нескольким таблицам приведет к удару производительности. Не бойтесь нормализовать, потому что вам нужно будет объединиться. Соединения являются нормальными и ожидаются в реляционных баз данных, и они предназначены для их эффективного управления. Вам нужно будет установить отношения PK/FK (для целостности данных, это важно учитывать при проектировании), но во многих базах данных FK автоматически не индексируются. Поскольку они будут использоваться в соединениях, вы обязательно захотите начать с индексации FKS. ПК обычно получают индекс при создании, поскольку они должны быть уникальными. Верно, что конструкция datawarehouse уменьшает количество объединений, но обычно не доходит до места хранения данных, пока в миллисекундах не требуется доступ к миллионам записей. Даже тогда почти все хранилища данных начинаются с транзакционной базы данных для сбора данных в режиме реального времени, а затем данные перемещаются на склад по расписанию (ночной или ежемесячный или независимо от потребностей бизнеса). Таким образом, это хороший старт, даже если вам нужно позже создать хранилище данных, чтобы улучшить производительность отчета.

Я должен сказать, что ваш дизайн впечатляет для первого студента CS.

1

Я работал в учебном/школьном домене, и я подумал, что хочу отметить, что в целом существует связь M: 1 между тем, что вы называете "сеансами" (экземплярами данного курса) и самим курсом. Другими словами, ваш каталог предлагает курс ( "испанский 101" или что-то еще), но у вас могут быть два разных экземпляра в течение одного семестра (Ту-т, преподаваемый Смитом, ср-пт, преподаваемым Джонсом).

Кроме этого, это выглядит неплохо. Бьюсь об заклад, вы обнаружите, что клиентский домен (графики, ведущие к "клиентам" ) сложнее, чем вы моделировали, но не переходите за борт, пока у вас нет реальных данных, которые помогут вам.

  • 0
    Если я вас правильно понял, это не совсем так. «Курсы» - это просто группы последующих сессий. Это не традиционная система, основанная на семестрах. Я не могу придумать ничего другого, что можно добавить в клиентский домен. У вас есть какой-нибудь пример? Кроме того, я был обеспокоен тем, что уже сошел со сложностью, рад, что это не так :) Спасибо за ваш вклад.
1

Это не слишком тщательно спроектировано, вот как я подхожу к проблеме. Присоединение в порядке, не будет большого количества ударов по производительности (это абсолютно необходимо, если вы не деформируете базу данных, что не рекомендуется!). Для статусов см., Если вы можете использовать тип данных перечисления вместо этого, чтобы оптимизировать эту таблицу.

  • 0
    Перечисления являются злом. Каждый раз, когда вам нужно расширить перечисление, вы должны перестраивать свою таблицу - это нормально, пока размер вашей таблицы не станет много ГБ.
  • 0
    Спасибо за вклад и предложение Крис, я волновался, что создам слишком сложного монстра. Мартин, статусы довольно четко определены и статичны: в основном 0-класс завершен, 1-класс отменен, 2-не появился. Я думаю, что эти три покрывают любой возможный результат класса. Это все еще плохая идея использовать перечисления в этом случае?
Показать ещё 2 комментария
0

Отличная работа!

Нет, вы не слишком сложны, вы отлично себя чувствуете. Я помню свой первый проект, это был веб-сайт, который я принял для создания, хотя я ничего не знал о программировании. Однако я его создал. Во всяком случае, вот некоторые полезные советы при построении первого проекта базы данных;

  • Держите таблицы маленькими (не тратьте ненужное пространство).

  • Не запрашивайте дополнительную информацию, чем вам нужно.

  • Если вы используете ORM, остерегайтесь распространенных ошибок, таких как проблема N + 1.

  • Держитесь подальше от неприятных операторов (например, "% Smith%" ).

  • Разработайте свои индексы разумно и убедитесь, что они покрывают большинство применений (здесь есть достойная, если светлая, обработка индексы).

  • Помните, что запрос на основе набора обычно намного превосходит производительность, чем повторение данных.

  • Знайте, когда денормализовать данные по причинам производительности.

  • все, что можно кэшировать (экономично), чтобы освободить БД.

Однако есть много инструментов, которые могут вам помочь. Например, я использую SQLDbm, который я считаю наиболее эффективным.

SQLDBM предлагает вам простой и удобный способ разработки вашей базы данных абсолютно в любом месте в любом браузере, без каких-либо дополнительных средств для работы с базами данных или инструментов моделирования баз данных или приложений. Используйте SQLDBM для проектирования и управления большими и малыми базами данных и моделями данных "на лету". Все, включая все необходимые правила и объекты базы данных, такие как ключи базы данных, схемы, индексы, ограничения столбцов и отношения.

0

Пришло в голову несколько вещей:

  • Таблицы, похоже, были направлены на отчетность, но на самом деле не выполняли бизнес. Я бы подумал, что когда клиент подписывается, по существу, заказ, который размещается для клиента, посещающего список сессий, и этот заказ может быть для нескольких сотрудников в одной компании. Казалось бы, таблица "порядок" действительно будет в центре вашей системы и будет управлять захватом данных и возможной отчетностью. (Сравните бумажные документы, которые вы использовали, чтобы запустить бизнес с вашим дизайном базы данных, чтобы увидеть, есть ли логическое совпадение.)

  • Компании часто не имеют подразделений. Сотрудники иногда меняют подразделения/отделы, возможно, даже в середине сессии. Компании иногда добавляют/удаляют/переименовывают подразделения/отделы. Убедитесь, что возможное изменение содержимого в реальном времени ваших таблиц не затрудняет последующую отчетность/группировку. С таким большим количеством контактных данных, разделенных на столько таблиц, вам может потребоваться очень строгая проверка ввода данных, чтобы ваши отчеты были значимыми и содержательными. Например, когда добавляется новый клиент, удостоверяясь, что его компания/подразделение/отдел/город соответствуют тем же значениям, что и его коллеги.

  • Концепция "пакеты" не совсем понятна.

  • Поскольку вы указываете на это малый бизнес, было бы удивительно, если бы производительность была проблемой, учитывая скорость и емкость существующих машин.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню