Новое проектирование баз данных: я - сверхразработка? [закрытый]

Фон

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

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

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

Мы можем начать иметь международные клиенты скоро, таким образом, я хочу, чтобы база данных не взорвалась, если/когда это происходит. У нас также в настоящее время есть пара крупных корпораций как клиенты, с различными подразделениями (например, компания-учредитель Высшей ТОЧКИ, подразделение здравоохранения ВЫСШЕЙ ТОЧКИ, ВЫСШАЯ ТОЧКА bodycare подразделение)

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

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

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

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

Пример запрашивает, я буду работать

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

Вопрос (вопросы)

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

Спасибо за внимание

244
задан Glorfindel 20 June 2019 в 15:05
поделиться

11 ответов

select 'table1', * from table1 
union
select 'table2',* from table2
-121--4648264-

Дополнительные ответы на ваши вопросы:

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

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

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

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

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

42
ответ дан 23 November 2019 в 03:09
поделиться

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

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

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

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

6
ответ дан 23 November 2019 в 03:09
поделиться

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

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

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

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

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

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

С уважением.

3
ответ дан 23 November 2019 в 03:09
поделиться

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

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

3
ответ дан 23 November 2019 в 03:09
поделиться

Нет. Похоже, вы проектируете с хорошей детализацией.

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

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

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

6
ответ дан 23 November 2019 в 03:09
поделиться

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

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

2
ответ дан 23 November 2019 в 03:09
поделиться

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

boost::shared_ptr<int> myFunction2()
{
    boost::shared_ptr<int> x = new int; 

    *x = 4; 
    return x;
}

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

-121--3250390-

Один шаг за раз.

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

Параллельно определите синтаксис для ссылки на переменные, массивы, хеши, числовые литералы, строковые литералы и другие строковые литералы. Также параллельно определите модель именования данных и правила определения области.

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

Напишите все это в EBNF и запустите его через ANTLR или подобное.

Также лучше не изобретать колесо заново. Я обычно начинаю с выбора последовательностей для запуска и завершения блоков и функций операторов и математических операторов, которые обычно являются принципиально C-подобными, ECMAScript-подобными, Basic-подобными, command-list или XML-основанными. Это очень помогает, потому что это то, с чем люди привыкли работать.

Конечно, вы должны придумать довольно убедительную причину не отказываться от написания нового языка и просто придерживаться C, ECMAScript или Basic, которые хорошо проверены и широко используются.

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

Если ваша цель - скорость разработки для какого-то конкретного проекта, вам может быть лучше создавать прототипы в таких областях, как Python, Lua или SpireMonkey, если вы хотите быстро встать и работать и хотите уменьшить количество типирования, необходимое в большинстве компилируемых языков.

-121--1527099-

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

1
ответ дан 23 November 2019 в 03:09
поделиться

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

В остальном это похоже на хорошее начало. Готов поспорить, вы обнаружите, что клиентская область (графики, ведущие к «клиентам») более сложна, чем вы моделировали, но не переусердствуйте с этим, пока у вас не будет реальных данных, которые помогут вам.

1
ответ дан 23 November 2019 в 03:09
поделиться

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

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

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

14
ответ дан 23 November 2019 в 03:09
поделиться

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

5
ответ дан 23 November 2019 в 03:09
поделиться

На ум пришло несколько вещей:

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

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

  3. Понятие «стая» совершенно неясно.

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

0
ответ дан 23 November 2019 в 03:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: