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

Фон

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

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

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

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

Схема, которую я придумал, следующая:

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

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

alt text
(источник: maian.org)

Примеры запросов, которые я буду выполнять

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

Вопросы)

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

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

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

  • В таблице 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.

С уважением.

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

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

Ответ 11

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

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

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

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

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

Ответ 12

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

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

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

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

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

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

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

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

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

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

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

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