Синхронизация перечисления и таблицы

11

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

  Положение дел
  Идентификатор описания
  --------------
   0 необработанных
   1 ожидание
   2 Обработано
   3 Ошибка

В моей программе мне нужно определить Id статуса для другой таблицы или, возможно, обновить запись с новым Id статуса.

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

Каков правильный подход для синхронизации этих двух, перечисления и таблицы?

MPelletier
источник
Почему вы держите вещи в синхронизации, а не в синхронизации? Синхронизация (скажи это) странно!
MrFox
1
@suslik Они оба произносятся одинаково. Синхронизация и синхронизация .
MPelletier
1
Наличие перечисления и таблицы базы данных является дублированием. Если таблица базы данных не будет использоваться другими приложениями, я бы отказался от этой таблицы и просто использовал бы enum. Если таблица будет использоваться в нескольких приложениях, вместо этого загрузите статусы из базы данных во время выполнения.
Питер Смит
Это зависит от контекста. В этом случае, будучи значениями рабочего процесса или состояния задачи, я бы предпочел сохранять их более динамичными, чем статическими, поскольку процессы часто имеют тенденцию изменяться; и имеют тенденцию менять внешнюю линию для графиков выпуска программного обеспечения. С другой стороны, если это стабильный сервис, в который вряд ли будут введены новые состояния или удалены существующие состояния, я мог бы быть более вынужден жестко закодировать их перечисление / денормализацию (в зависимости от того, как записи используются позже).
JustinC
@PeterSmith База данных не может применять ограничения, если они есть только в вашем перечислении Java, а не в таблице. Вы собираетесь ограничивать значения в своей базе данных, не так ли?
Дэвид Конрад

Ответы:

5

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

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

Мэтью
источник
Речь идет не столько о новых статусах (что определенно потребует модификации базы данных и программы), а о значениях идентификаторов.
MPelletier
2
Я не понимаю, почему вы изменили бы значение идентификатора, не меняя его значения. Перечисления такого рода не будут автоматически увеличиваться, и они на самом деле просто для удобства чтения для людей, отлаживающих базу данных, поскольку обычно ваше приложение будет делать запросы, и оно уже будет знать, каким будет идентификатор pending. Конечно, наличие Statusтаблицы дает вам ссылочную целостность, но это помимо того, что я пытаюсь сделать.
Мэтью
Ну да, это идея. Но если я устанавливаю идентификаторы в одно место для других, я работаю на предположении, что они оба правы. Это свободная ссылка, нет?
MPelletier
3
Мы делаем эти допущения постоянно, если вы думаете об определении таблицы, наша программа предполагает, что определение является таковым при написании запроса. StatusТаблицу не следует рассматривать как динамические через время выполнения приложения, и , таким образом , я не думаю , что вы должны прочитать его как таковые.
Мэтью
8

Обычно я загружаю эти данные в статический кеш (обычно в HashMap или что-то в этом роде) при запуске приложения. Это позволяет избежать перекомпиляции только потому, что enum был каким-то образом модифицирован.

FrustratedWithFormsDesigner
источник
2

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

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

Обычно у меня есть небольшой фрагмент кода, который подключается к БД и проверяет, что все состояния, перечисленные в конкретной таблице, имеют те же значения идентификатора / имени, которые я жестко запрограммировал в памяти. Если они не совпадают, я прерву выполнение программного обеспечения.

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

Alex
источник
2

У нас схожие проблемы с моим проектом (унаследованный код, ура!). Основная проблема заключается в том, что «таблицы enum никогда не меняются», пока они не изменятся и не произойдет разрыв кода. У меня есть две стратегии смягчения, к которым я медленно перемещался.

Во-первых, и лучше всего, по возможности, исключить прямые ссылки на эти значения. Всегда спрашивайте: «Зачем мне напрямую использовать значение перечисления?» Во многих случаях это признак того, что в коде слишком много жестко закодированных предположений или он пытается слишком много манипулировать данными. Посмотрите, не можете ли вы создать более совершенные отношения в базе данных или более гибкий код для обработки того, чем манипулируют.

Когда это не работает, я перехожу к плану B: генерация кода. Поскольку таблицы меняются нечасто, и мы регулярно публикуем новые сборки, генератор кода может читать таблицы enum и писать код enum. Эта динамически генерируемая библиотека затем используется в проекте. Если БД изменится, следующая сборка не будет скомпилирована, что намного лучше, чем таинственные ошибки во время выполнения.

CodexArcanum
источник
Как бы вы исключили ссылки на перечисление? Например, вы сортируете или ищете по статусу в этом случае. Наличие некоторой магической ценности в БД меня тоже не устраивает. Вот для чего нужны таблицы поиска.
nportelli
В прошлом я делал наоборот. Всякий раз, когда происходит изменение кода в Enum, при загрузке приложения оно синхронизирует эти значения с базой данных. Здесь код является источником правды. База данных является его представлением. Обычно я игнорирую значения в БД, которые код не может понять, но таким образом я получаю механизм для автоматической очистки БД, если это необходимо.
Аньшул