Задача - хранить код и строки БД отдельно - PullRequest
0 голосов
/ 26 июня 2009

Мы все согласны с тем, что база данных предназначена для хранения и что код не должен быть тесно связан с ней. Как вы этого добиваетесь, когда храните настройки в БД. Позвольте мне привести пример.

Предположим, вы создаете небольшой онлайн-опрос. Каждый опрос может иметь «тип голосования». Вот несколько типов голосования:

  • Анонимное голосование
  • IP-голосование
  • и т.д.

Теперь, если есть интерфейс, где пользователь создает опрос и сохраняет «тип голосования», кажется неизбежным, что в какой-то момент вы связываете что-то в БД (либо первичный ключ, либо имя) с кодом, который делает «анонимное голосование», «IP-голосование» и т. д.

В другом, но связанном вопросе Джон Сандерс сказал, что это глупо - и я с ним полностью согласен! Зачем подключать БД и код - это плохая идея. Но как избежать этого, если вы храните что-то вроде «типа голосования»?

Ответы [ 8 ]

1 голос
/ 26 июня 2009

Просто определите некоторые константы, находятся ли они в перечислении или что-то, что поддерживает ваш язык, например

enum VoteType { Anon = 1, IP = 2, ... }

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

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

0 голосов
/ 26 июня 2009

Давайте предположим, что вы создаете класс, который фактически выполняет тяжелую работу по выяснению того, что должен делать VoteType (чтобы он мог проверять такие вещи, как is_another_vote_available) и т. Д. Таким образом, вы могли бы иметь:

  • VoteTypeIpSingleVote: это позволяет один голос за IP-адрес
  • VoteTypeAnonymous: для этого голосования нет ограничений.

В БД у вас будут записи в таблице VoteType:

  • 1 однопользовательское голосование
  • 2 Аноним

Затем вы могли бы создать интерфейс, который реализуют все VoterTypes (VoteTypeAnonymous и т. Д.), Который имеет свойство "VoteType", которое возвращает либо

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

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

Чтобы вы могли позвонить:

id = fetchVoteTypeToBeUsedFromDb

manager.getVoteType (id) .is_available (datetime.now ())

И таким образом можно легко добавить новые типы голосования, просто зарегистрировавшись и не требуя постоянного обновления оператора switch.

0 голосов
/ 26 июня 2009

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

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

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

0 голосов
/ 26 июня 2009

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

Другая причина заключается в том, что трудно превзойти простоту внесения изменений в код в текстовых файлах, а не в базе данных.

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

Однако очень редко можно увидеть случай, когда это так.

0 голосов
/ 26 июня 2009

Вы могли бы иметь перечисление. В C # что-то вроде:

public enum VoteType
{
    ANONYMOUS,
    IP_BASED,
    OTHER
}

и затем в коде вы просто говорите что-то вроде

switch(vote.Category)
{
   case VoteType.ANONYMOUS: //do stuff
   case VoteType.IP_BASED: //do some other stuff
   //etc
}

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

0 голосов
/ 26 июня 2009

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

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

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

getAnonVotingTypeName () getIpBasedVotingTypeName () и т.д ..

Таким образом, если имена когда-либо изменились, вам нужно будет изменить их только в одном классе (и, конечно, обновить существующие записи в таблицах).

0 голосов
/ 26 июня 2009

Единственное, что нужно сделать, это просто сохранить настройки в виде XML в столбце XML в базе данных. Тогда базе данных не важно, что будет сохранено - это зависит от кода, чтобы выяснить это.

0 голосов
/ 26 июня 2009

Поправьте меня, если я ошибаюсь, но разве вы не можете просто сохранить vote_type field в своем Polls table? Если в качестве аргумента голосования используется ip, вы используете функцию storeVoteByIP(). Если это userID, вы используете метод storeVoteByID() - или один метод с переключателем.

Возможно, я просто наивен, но я не вижу здесь проблемы:)

switch($vote_type) {
  case 1:
    #insert_vote_by_ip();
    break;
  case 2:
    #insert_vote_by_userid();
    break;
  ...
}

Чего мне не хватает?

...