Разработка БД для расписания - PullRequest
1 голос
/ 23 октября 2010

Я создаю веб-приложение, в котором пользователи должны иметь возможность указывать свое еженедельное расписание. Вот моя модель БД для этого:

id
user_id
day
from
to

day - это перечисление 0-6 (0 для воскресенья, 1 для понедельника и т. Д.). from и to представляют минуты с полуночи. Итак, 0 означает полночь, 1 означает 12:01, 2 означает 12:02 и т. Д.

Это хороший дизайн? Есть ли потенциальные проблемы с ним?

Что если бы я хотел показывать больше недели? Как бы я справился с этим? Сейчас я просто показываю график работы на неделю, но было бы неплохо иметь возможность указать больше.

Ответы [ 4 ]

3 голосов
/ 25 октября 2010

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

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

  2. База данных.
    Если вам нужны возможности базы данных (поиск, целостность, возможность восстановления), то обязательно поместите ее в базу данных. Вы можете предоставить открытую (защищенную, но открытую) базу данных, чтобы пользователи могли опрашивать базу данных без необходимости проходить через ваше приложение; не ограничиваясь функциями, предоставляемыми вашим приложением. Например. создать любой отчет, который они хотят с любым инструментом отчета. Большинство людей обнаружили, что это приводит к меньшему количеству кодирования для них. Для этого вам нужно читать и изучать базы данных. .
    .
    Базы данных имеют такие понятия, как домены и типы данных. Потребность в них, чтобы они могли выполнять согласованные функции помимо самих данных, была определена 40 лет назад и представлена ​​в стандартизированной форме более 30 лет назад. Позвольте мне привести один пример. Перечисленное целое число, которое, как утверждается, содержит номер дня, бесполезно никому, кроме вас, и оно очень и очень ограниченно думает (обратите внимание, что из ваших вопросов даже вы понимаете, что существуют ограничения для любого вида навигации за пределами одной недели). ANSI SQL предоставляет тип данных DATE и DATETIME. .
    .
    Если вы используете их:

    • любой может легко проверить ваши столбцы даты
    • и, что более важно, они могут выполнять арифметику дат и сравнивать их, используя функции Date, которые поставляются с программным обеспечением базы данных, без необходимости проходить через ваше приложение
    • Кроме того, вы можете использовать те же функции и функции в своем приложении и сократить время, затрачиваемое на их кодирование.
    • Все ваши вопросы и ограничения устранены. (Вам все равно придется прочитать, как это так; как отобразить форматы даты, выполнить арифметику даты ... очень похоже на использование библиотеки).
      ,
  3. Необработанный файл, расположенный в базе данных.
    Если вы поместите свой файл в базу данных, не изучая базы данных, их возможности, методы моделирования данных, тогда у вас все равно будет файл, ограниченный вашими ограниченными возможностями. Это остается файл без возможности базы данных, только то, что он находится где-то на платформе базы данных. Нахождение файла перечислений в базе данных не волшебным образом помазывает его возможностями базы данных (размещение нормализованных и совместимых структур в базе данных делает). Все ваши вопросы и ограничения останутся.

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

Наконец, и Дейв совершенно прав, вы никогда, даже через 20 жизней, никогда не приблизитесь даже к функции обработки даты в вашем приложении, которую поставщики уже предоставили в своем приложении.Я тоже не смогу подойти к этому.Поэтому, пожалуйста, не изобретайте велосипед заново.

Примите во внимание требования и выберите, какой вариант вы хотите, и дайте нам знать, чтобы мы могли вам помочь.Если вы действительно не хотите [2], удалите тег базы данных.

================================

Ответы на последующие комментарии

  1. Спасибо.На вопросы легко ответить.Заявления о вещах, которые вы не знаете, являются, ну, аргументом.

  2. Да, в вашем подходе есть серьезные ограничения.Вы не можете предоставить расписание только на одну неделю.Неделя не существует изолированно: она существует в контексте месяца, года, месяца года и т. Д. Ваша неделя не позволяет бронированию переходить с пятницы на вторник.Даже для предложенной недели, он не поставляет неделю полностью.И да, это не может быть расширено или расширено, чтобы обеспечить больше чем фиксированная неделя.Вот почему каждый предлагает ДАТУ;это освободит вашу неделю от оков.Для разумного графика вам нужно гораздо больше, но вы не задавали этот вопрос.

  3. Дата.Если вам надоело (это все в руководствах и доступно онлайн) прочитать о DATE/TIME/DATETIME типах данных, вы найдете: он содержит все date_parts;вы используете только нужные вам date_parts (например, DayOfWeek) и другие по умолчанию;он позволяет вам выполнять арифметику дат и сравнения всех date_parts (например, DayOfMonth), без каких-либо проблем.Очевидно, что вы не должны выполнять такие операции над компонентами Date, которые вы сознательно не устанавливали.Давайте назовем ваш «стол» WeekSchedule:

<code>CREATE TABLE (
    -- I cannot see the need for an "id" so it is excluded
    UserId        INT           NOT NULL,
    MeetingName   CHAR(30)      NOT NULL,
    StartDateTime SMALLDATETIME NOT NULL,
    EndDateTime   SMALLDATETIME NOT NULL,
    ...
    )
CREATE UNIQUE CLUSTERED INDEX UC_PK
    ON WeekSchedule (UserId, StartDateTime)
    -- double bookings eliminated, in addition to providing decent key

Например.установить StartDateTime на текущую дату по умолчанию и время начала встречи;EndDateTime - текущая дата по умолчанию и время окончания собрания.Поскольку вы загрузили только ЧЧ: ММ, не проверяйте YY.MM.DD или DoW, DoM или WoY.В то же время, другие могут проверить его, используя:

<code>
    DATEADD(date_part, integer, date_expression)
    DATEDIFF(date_part, date_expression1, date_expression2)
    DATEPART(date_part, date_expression)
    DATENAME(date_part, date_expression)
    -- RTM for further details 
    -- Dave has already provided example display formats
и т. Д., Без необходимости спрашивать вас, что такое контент, означает ли 1 воскресенье или понедельник, используете ли вы запись военного времени или аналоговое лицо и т. Д.

Позже, когда вы реализуете структуры и таблицы, необходимые для поддержки межнедельных собраний (или месячного расписания, или повторяющихся собраний), вы обнаружите, что WeekSchedule уже поддерживает это, никаких структурных изменений не требуется;просто загрузите столбцы StartDateTime с фактической датой и временем начала встречи;EndDateTime с фактической датой и временем окончания собрания.

2 голосов
/ 25 октября 2010

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

Для такого использования, регулярного, повторяющегося еженедельного расписания, ваш дизайн в порядке. Я бы сделал FROM и TO столбцами TIME, а не целыми числами, но это все.

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

2 голосов
/ 23 октября 2010

Пожалуйста, не изобретайте велосипед.Это одно из самых мощных решений по программированию и разработке чего-либо.

Я имею в виду следующее: каждый раз, когда у вас есть возможность полагаться на встроенный или нативный тип, вы должны его использовать.В полях день , от и до вы можете и должны рассмотреть возможность использования соответствующих собственных типов, таких как Дата , Дата и время , Отметка времени .

Кроме того, если вам требуется извлекать, фильтровать и т. Д. Эти данные, вы можете использовать встроенные функции.

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

Я бы сделал эту базу данных такой:

id -- autoincrement
Start -- datetime
End --datetime

Я полагаю, у вас есть таблица пользователей.И я бы добавил еще одну таблицу UsersSchedule, например:

user_id -- FK to users
schedule_id -- FK to schedule

Таким образом, многие пользователи могут быть зарегистрированы на одно и то же собрание или событие.Конечно, это может пойти еще дальше и добавить другие управляющие поля, такие как EventName, EventPromoter (user_id от пользователя-инициатора), Invites (список идентификаторов пользователей, приглашенных на событие), Atendees (список user_id людей, которые подтвердили / подтвердили событие) ... но это решение за вами.

Обратите внимание, что я бы интенсивно использовал функции DateTime (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html), чтобы сэкономить на логическом программировании, например проверять сегодняшние события, запланированные для конкретного пользователя)., конфликтующие события для конкретного пользователя и т. Д.

Ну, я думаю, у вас есть идея.

РЕДАКТИРОВАТЬ

Предположим, у вас есть одна запись типа:

id   |        start        |        end
45   | 2010-10-25 09:00:00 | 2010-10-25 18:00:00

Вы можете выполнить запрос:

SELECT CONCAT(
DATE_FORMAT(start, '%a'), ', ',
DATE_FORMAT(start, '%l%p'), ' - ',
DATE_FORMAT(end, '%l%p')
) as Event FROM schedule WHERE id = 45;

, который даст вам следующий вывод:

Mon, 9AM - 6PM

Готово.

2 голосов
/ 23 октября 2010

При первой же мысли я постараюсь сделать дизайн немного более открытым. Что-то вроде

id
User_id
Date
Start_Time
End_Time

Таким образом, вы не ограничиваетесь одной неделей. Кроме того, работа с датами и временем упрощает вычисления. Имея их, довольно легко узнать день недели, минуты с полуночи и т. Д.

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

Этот дизайн предполагает, что у вас не будет расписаний, начинающихся на один день и заканчивающихся на следующий. В этом случае вам потребуется Start_Date и End_Date.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...