Задний план
Я студент первого курса CS, и я работаю неполный рабочий день для малого бизнеса моего отца. У меня нет никакого опыта в разработке приложений реального мира. Я написал сценарии на Python, некоторые курсовые работы на C, но ничего подобного.
У моего отца небольшой учебный бизнес, и в настоящее время все занятия планируются, записываются и отслеживаются с помощью внешнего веб-приложения. Существует функция экспорта / «отчетов», но она очень общая, и нам нужны конкретные отчеты. У нас нет доступа к фактической базе данных для выполнения запросов. Меня попросили настроить систему отчетности.
Моя идея состоит в том, чтобы создать общий экспорт CSV и импортировать их (возможно, с помощью Python) в базу данных MySQL, размещаемую в офисе каждую ночь, откуда я могу выполнять конкретные запросы, которые необходимы. У меня нет опыта работы с базами данных, но я понимаю основы. Я прочитал немного о создании базы данных и нормальных формах.
Мы можем начать иметь международных клиентов в ближайшее время, поэтому я хочу, чтобы база данных не взорвалась, если / когда это произойдет. У нас также есть несколько крупных корпораций в качестве клиентов с различными подразделениями (например, материнская компания ACME, отдел здравоохранения ACME, отдел ухода за телом ACME)
Схема, которую я придумал, следующая:
- С точки зрения клиента:
- Клиенты это основной стол
- Клиенты связаны с отделом, в котором они работают
- Отделы могут быть разбросаны по всей стране: HR в Лондоне, маркетинг в Суонси и т. Д.
- Отделы связаны с подразделением компании
- Подразделения связаны с материнской компанией
- С точки зрения классов:
- Сессии является основной таблицей
- Учитель связан с каждой сессией
- Статус предоставляется каждому сеансу. Например, 0 - Завершено, 1 - Отменено
- Сессии сгруппированы в «пачки» произвольного размера
- Каждый пакет назначается клиенту
- Сессии является основной таблицей
Я «спроектировал» (точнее, набросал) схему на листе бумаги, стараясь, чтобы она нормализовалась до 3-го класса. Затем я подключил его к MySQL Workbench, и это сделало все это красивым для меня:
( Нажмите здесь для полноразмерной графики )
(источник: maian.org )
Примеры запросов, которые я буду выполнять
- Какие клиенты с кредитом все еще остались неактивными (те, у кого не запланировано обучение в будущем)
- Какова посещаемость на клиента / отдел / подразделение (измеряется идентификатором статуса в каждой сессии)
- Сколько занятий у учителя за месяц
- Пометить клиентов с низкой посещаемостью
- Пользовательские отчеты для отделов кадров с показателями посещаемости людей в их отделе
Вопросы)
- Это слишком силен или я направляюсь в правильном направлении?
- Приведет ли необходимость объединять несколько таблиц для большинства запросов к значительному снижению производительности?
- Я добавил колонку «lastsession» для клиентов, поскольку это, вероятно, будет общий запрос. Это хорошая идея, или я должен держать базу данных строго нормализованной?
Спасибо за ваше время
источник
divisions
имеет столбец с именемdivisionid
. Разве вы не находите это излишним? Просто назови этоid
. также имена ваших таблиц, в том числе_has_
: я бы удалил это и просто назвал его, напримерcities_departments
. ВашиDATETIME
столбцы должны иметь тип,TIMESTAMP
если они не являются пользовательскими значениями. Я думаю , что это хорошая идея , чтобы иметьcities
иcountries
таблицу. Вы можете столкнуться с проблемами, ограничивающими таблицы однимstatus
. рассмотрите возможность использованияINT
и выполнения побитовых сравнений, чтобы вы могли иметь больше смыслаОтветы:
Еще несколько ответов на ваши вопросы:
1) Вы в значительной степени ориентированы на того, кто впервые сталкивается с такой проблемой. Я думаю, что указатели других по этому вопросу до сих пор в значительной степени охватывают его. Хорошая работа!
2 и 3) Удар производительности, который вы получите, будет в значительной степени зависеть от наличия и оптимизации правильных индексов для ваших конкретных запросов / процедур и, что более важно, от объема записей. Если вы не говорите о более чем миллионе записей в ваших основных таблицах, вы, похоже, идете по пути к достаточно массовому дизайну, чтобы производительность не была проблемой на разумном оборудовании.
Тем не менее, и это относится к вашему вопросу 3, с самого начала вы, вероятно, не должны слишком беспокоиться о производительности или гиперчувствительности к нормализации ортодоксальности. Это сервер отчетов, который вы создаете, а не серверная часть приложения на основе транзакций, которая имеет совершенно другой профиль в отношении важности производительности или нормализации. База данных, поддерживающая приложение для прямой регистрации и планирования, должна учитывать запросы, которые возвращают данные за считанные секунды. Мало того, что функция сервера отчетов обладает большей терпимостью к сложным и длительным запросам, но и стратегии повышения производительности сильно отличаются.
Например, в среде приложений на основе транзакций ваши варианты улучшения производительности могут включать рефакторинг ваших хранимых процедур и структур таблиц до n-й степени или разработку стратегии кэширования для небольших объемов часто запрашиваемых данных. В среде отчетности вы, безусловно, можете сделать это, но вы можете оказать еще большее влияние на производительность, внедрив механизм моментальных снимков, при котором запланированный процесс запускается и сохраняет предварительно сконфигурированные отчеты, а ваши пользователи получают доступ к данным моментальных снимков без нагрузки на уровень БД. на основе запроса.
Все это - многословная рутина, иллюстрирующая, что принципы и приемы проектирования, которые вы используете, могут отличаться в зависимости от роли создаваемого вами БД. Я надеюсь, что это полезно.
источник
У тебя правильная идея. Однако вы можете очистить его и удалить некоторые из таблиц сопоставления (имеет *).
То, что вы можете сделать, это в таблице Департаментов, добавить CityId и DivisionId.
Кроме того, я думаю, что все в порядке ...
источник
Единственные изменения, которые я хотел бы сделать:
1- Измените VARCHAR на NVARCHAR, если вы собираетесь выходить на международный уровень, вы можете захотеть использовать Unicode.
2. Если возможно, измените свои int id на GUID (uniqueidentifier) (это может быть только мое личное предпочтение). Предполагая, что вы в конечном итоге дойдете до точки, где у вас есть несколько сред (dev / test / staging / prod), вы можете захотеть перенести данные из одной в другую. Наличие идентификатора GUID делает это значительно проще.
3- Три слоя для вашей компании -> Отдел -> Структура отдела может быть недостаточно. Теперь это может быть чрезмерно сложно, но вы можете обобщить эту иерархию так, чтобы вы могли поддерживать n уровней глубины. Это сделает некоторые ваши запросы более сложными, так что это может не стоить компромисса. Кроме того, может случиться так, что любой клиент, который имеет больше слоев, может быть легко «вписан» в эту модель.
4- У вас также есть статус в таблице клиентов, который является VARCHAR и не имеет ссылки на таблицу статусов. Я ожидал бы немного большей ясности относительно того, что представляет собой статус клиента.
источник
Нет. Похоже, вы разрабатываете на хорошем уровне детализации.
Я думаю, что страны и компании - это одно и то же лицо в вашем дизайне, как и города и отделы. Я бы избавился от таблиц стран и городов (и Cities_Has_Departments) и, при необходимости, добавил бы логический флаг IsPublicSector в таблицу Companies (или столбец CompanyType, если есть больше вариантов, чем просто частный сектор / государственный сектор).
Кроме того, я думаю, что вы используете ошибку в таблице отделов. Похоже, таблица «Отделы» служит ссылкой на различные виды отделов, которые могут иметь каждое клиентское подразделение. Если это так, он должен называться DepartmentTypes. Но ваши клиенты (которые, я полагаю, посетители) не принадлежат к типу отдела, они принадлежат фактическому экземпляру отдела в компании. В нынешнем виде вы будете знать, что данный клиент относится к отделу кадров где-то, а не к какому!
Другими словами, клиенты должны быть связаны с таблицей, которую вы называете Divisions_Has_Departments (но я бы назвал ее просто Departments). Если это так, то вы должны свернуть Города в Подразделения, как обсуждалось выше, если вы хотите использовать стандартную ссылочную целостность в базе данных.
источник
Кстати, стоит отметить, что если вы уже генерируете CSV и хотите загрузить их в базу данных MySQL, LOAD DATA LOCAL INFILE - ваш лучший друг: http://dev.mysql.com/doc/refman/5.1/ ru / load-data.html . Mysqlimport также заслуживает изучения и представляет собой инструмент командной строки, который, по сути, является хорошей оболочкой для загрузки данных.
источник
Большинство вещей уже было сказано, но я чувствую, что могу добавить одну вещь: молодые разработчики довольно часто беспокоятся о производительности слишком заранее, и ваш вопрос о присоединении к таблицам, похоже, идет в этом направлении. Это анти-паттерн разработки программного обеспечения под названием « Преждевременная оптимизация ». Попробуй изгнать этот рефлекс из головы :)
Еще одна вещь: вы считаете, что вам действительно нужны таблицы «городов» и «стран»? Разве для ваших сценариев использования недостаточно столбцов «город» и «страна» в таблице отделов? Например, ваше приложение должно перечислить департаменты по городам и городам по странам?
источник
Следующие комментарии основаны на роли специалиста по бизнес-аналитике / отчетности и менеджера по стратегии / планированию:
Я согласен с указанием Ларри выше. ИМХО, это не так уж и сложно, некоторые вещи выглядят немного не к месту. Чтобы было проще, я бы привязал клиента непосредственно к идентификатору компании, описанию отдела, описанию отдела, идентификатору типа отдела, идентификатору типа отдела. Используйте идентификатор типа отдела и идентификатор типа подразделения в качестве ссылок на таблицы поиска и внутренние поля отчетности / анализа для обеспечения долгосрочной согласованности.
Таблица пакетов содержит столбец «Кредит», разве это не должно быть связано с базовой таблицей Клиента, поэтому, если их много, вы можете увидеть, сколько кредитов осталось для будущих классов? Приложение может заботиться о калькуляции и хранить его централизованно в таблице клиентов.
Информация о компании может использовать гораздо больше полей, включая очевидный адрес / телефон / и т. Д. Информация. Я также был бы готов добавить в столбцы D & B "DUN" (Site / Branch / Ultimate) долгосрочные данные, так как Dun and Bradstreet (D & B) имеют огромный каталог компаний, и позже вы обнаружите, что их информация очень полезна для отчетности / анализа. Это позаботится о проблеме множественного разделения, которую вы упомянули, и позволит вам свернуть их иерархию для подразделов / подразделений / филиалов / и т. Д. большого корпуса.
Вы не упоминаете, с какими записями вы будете работать, и это может означать, что вы настроите себя на крупную инициативу по разработке, которая могла бы быть выполнена быстрее и с гораздо меньшими головными болями с помощью предварительно упакованного программного обеспечения для «отчетности». Если вы не имеете дело со строками большой базы данных (<65000), убедитесь, что решения MS-Access, OpenOffice (Base) или связанные с ними приложения для разработки отчетов / приложений не справились с задачей. Я сам немного использую бесплатное программное обеспечение Oracle APEX, оно поставляется с бесплатной базой данных Oracle XE, просто скачайте его с их сайта.
К сведению: представление отчетности: для больших баз данных у вас обычно есть два экземпляра базы данных: а) база данных транзакций для записи каждой подробной записи. б) база данных отчетов (витрина данных / хранилище данных), размещенная на отдельном компьютере. Для получения дополнительной информации выполните поиск в Google Star Schema и Snowflake Schema.
С уважением.
источник
Я хочу остановиться только на том, что присоединение к нескольким таблицам повлечет за собой снижение производительности. Не бойтесь нормализоваться, потому что вам придется делать объединения. Соединения нормальны и ожидаемы в реляционных базах данных, и они разработаны для того, чтобы хорошо с ними справляться. Вам нужно будет установить отношения PK / FK (для целостности данных это важно учитывать при проектировании), но во многих базах данных FK не индексируются автоматически. Так как они будут использоваться в соединениях, вы определенно захотите начать с индексации FKS. ПК обычно получают индекс при создании, поскольку они должны быть уникальными. Это правда, что дизайн хранилища данных уменьшает количество объединений, но обычно не удается добраться до хранилища данных до тех пор, пока в одном отчете не будут доступны миллионы записей. Даже тогда почти все хранилища данных начинают с транзакционной базы данных для сбора данных в режиме реального времени, а затем данные перемещаются в хранилище по расписанию (ночью или ежемесячно или в соответствии с потребностями бизнеса). Так что это хорошее начало, даже если вам нужно спроектировать хранилище данных позже, чтобы повысить производительность отчетов.
Я должен сказать, что ваш дизайн впечатляет для студентов первого курса CS.
источник
Это не слишком сложно, так я бы подошел к проблеме. Присоединение - это хорошо, производительность не сильно снизится (это совершенно необходимо, если вы не нормализуете базу данных, что не рекомендуется!). Для статусов посмотрите, можете ли вы вместо этого использовать тип данных enum для оптимизации этой таблицы.
источник
Я работал в области обучения / школы, и я подумал, что должен указать, что обычно существует отношение M: 1 между тем, что вы называете «сессиями» (экземплярами данного курса), и самим курсом. Другими словами, ваш каталог предлагает курс («Испанский 101» или любой другой), но у вас может быть два разных экземпляра в течение одного семестра (Tu-Th, преподаваемый Smith, Wed-Fri, преподаваемый Jones).
Кроме того, это выглядит как хорошее начало. Могу поспорить, вы обнаружите, что клиентский домен (графики, ведущие к «клиентам») является более сложным, чем вы смоделировали, но не переусердствуйте с этим, пока у вас не появятся реальные данные, которые вам помогут.
источник
На ум пришло несколько вещей:
Таблицы казались ориентированными на отчетность, но на самом деле не управляли бизнесом. Я думаю, что когда клиент регистрируется, по сути, размещается заказ для клиента, посещающего список сеансов, и этот заказ может быть для нескольких сотрудников в одной компании. Может показаться, что таблица «порядка» действительно будет в центре вашей системы и будет управлять сбором данных и возможной отчетностью. (Сравните бумажные документы, которые вы использовали для ведения бизнеса, с дизайном базы данных, чтобы увидеть, есть ли логическое совпадение.)
Компании часто не имеют отделов. Сотрудники иногда меняют отделы / отделы, возможно, даже в середине сессии. Компании иногда добавляют / удаляют / переименовывают подразделения / отделы. Убедитесь, что возможное изменение содержимого ваших таблиц в реальном времени не затрудняет последующую отчетность / группировку. С таким большим количеством контактных данных, разбитых на множество таблиц, вам, возможно, придется применять очень строгую проверку ввода данных, чтобы ваши отчеты были содержательными и содержательными. Например, когда добавляется новый клиент, убедитесь, что его компания / подразделение / отдел / город соответствуют тем же значениям, что и его коллеги.
Концепция «пачки» не совсем понятна.
Поскольку вы указываете, что это небольшая компания, было бы удивительно, если бы производительность была проблемой, учитывая скорость и мощность современных машин.
источник