Когда один жестко кодирует реальные значения данных в коде, а не использует БД?

17

Давний вопрос для меня был: когда я храню данные (фактические значения) в таблице базы данных и когда я храню их прямо в коде?

Неизвестный консенсус, как правило, был таким (*):

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

[* консенсус обсуждался в комментариях и ответах, но в основном я хотел, чтобы какая-то посылка подтолкнула вопрос, так что не стесняйтесь оспаривать и улучшать его ]

Пример:

$number = 44;
$colors = array("blue", "yellow", ... "mauve");

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

Но, кажется, есть серая область; как насчет случаев, которые не так ясны? На какие соображения и факторы нужно обратить внимание, чтобы принять решение?

Пример.
Допустим, ваша компания использует 10-15 различных типов каркасов двигателей, которые можно представить как «412T». У вас их около 30, и они редко меняются. Вы можете создать таблицу БД для них или жестко закодировать их в базе данных. В этом случае двигатели являются статичными, физическими вещами, которые вряд ли будут часто меняться.

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

Другой (фактический) пример, который я могу использовать, - это мой вопрос: /programming/26169751/how-to-best-get-the-data-out-of-a-lookup-table (в настоящее время 48 строки опционных данных).

Деннис
источник
3
Неизвестный консенсус, как правило, НЕ таков: если это отдельная переменная, простая структура или массив из нескольких значений, поместите данные прямо в код.
Питер Б
Существует средний путь: данные хранятся в базе данных. Затем он извлекается для записи исходного кода (например, в global_constants.hфайле).
Mouviciel
@mouviciel, но что составляет данные ... вам нужны некоторые данные для доступа к базе данных, поэтому вы не можете хранить все данные там.
jwenting

Ответы:

33

Я не думаю, что эти два утверждения действительно представляют консенсус о том, когда нужно жестко кодировать данные:

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

Если в нем сотни и более строк данных одного типа, используйте базу данных

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

Вместо этого я бы сначала сосредоточился на вопросе:

  • Как часто данные меняются?

  • Кому может понадобиться это изменить?

Если ответ «как часто» - «чаще, чем я хочу развернуть новую версию моего приложения», тогда вам не следует жестко кодировать данные.

Если ответом «кто его меняет» является «кто-нибудь, кроме программиста», то вам не следует жестко кодировать данные.

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

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

х-код
источник
6
Подобно тому, как часто вопрос, другой вопрос, "Как быстро это должно измениться?" Фактором стробирования может быть то, сколько времени потребуется для развертывания в вашей пользовательской базе. Для программного обеспечения централизованного сервера ответ может быть минутным, но для мобильных приложений на местах это может занять недели.
CuriousRabbit
В примере с Perl я бы назвал его an array with a few valuesнемногими из 377 строк с базовым типом данных. Может быть, больше, чем «несколько» для некоторых, но это все еще довольно мало. У меня есть похожие, но немного менее плоские структуры, жестко закодированные. Если бы это было более тысячи строк, я бы, скорее всего, неохотно его так закодировал.
Деннис
14

Я бы пошел с третьим вариантом: файл конфигурации!

Для приложений, над которыми я работаю (в Java, поэтому все мои примеры используют Java + Spring), такие значения обычно хранятся в конфигурационных файлах и внедряются (через Spring) в код, который нуждается в них при запуске приложения. В файле свойств:

motorFramesString=412T, 413T, ...

В весеннем конфиге:

<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames" value="${motorFrames}"/>
</bean>

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

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


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

В продукции. Свойства:

productA.name=Product A 123
productA.hasMotor=true
productA.numFeet=1
productA.hasOutlet=true
productA.needsManual=true

productB.name=Product B 456
productB.hasMotor=false
productB.numFeet=1
productB.hasOutlet=true
productB.needsManual=true

В вашем весеннем конфигурационном файле:

<bean name="productA" class="com.mycompany.Product">
   <property name="name" value="${productA.name}"/>
   <property name="hasMotor" value="${productA.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<bean name="productB" class="com.mycompany.Product">
   <property name="name" value="${productB.name}"/>
   <property name="hasMotor" value="${productB.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<!-- configure as many beans as needed -->
<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames"> <!-- assumes that MotorFrameManager has a property motorFrames which is a List<Product> -->
        <list>
            <ref bean="productA"/>
            <ref bean="productB"/>
        </list>
    </property>
</bean>

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

FrustratedWithFormsDesigner
источник
пока вы находитесь на примере фрейма, это довольно просто (только одно строковое значение). Будет ли ваш подход в основном таким же для таблицы опций, в которой есть n-кортежи смешанных переменных (ссылки внизу моего вопроса)?
Деннис
@Dennis: добавлен более сложный пример.
FrustratedWithFormsDesigner
8
Файл конфигурации - это всего лишь одна из форм БД.
DougM
3
@ ДаугМ, я согласен, но существует огромная разница между настройкой серии таблиц конфигурации в Oracle и наличием простого файла конфигурации XML. Конфигурационный файл также обладает преимуществом управления версией. Конфигурационный файл - это золотая середина, который побуждает кодировщиков выделять больше конфигурационных данных. Я изо всех сил пытаюсь придумать реалистичные сценарии, где время это нехорошо
Макотл
2
@gbjbaanb: Для большинства приложений СУРБД является WAAAAAY излишним, даже для довольно обширных систем. Не говоря уже о том, что они медленные и требуют значительных усилий для поддержки и интеграции. «ini» -файлы не обеспечивают никакой безопасности типов, вы должны сами написать синтаксический анализатор и написать свою собственную проверку типов. Файлы XML Config, по крайней мере, в .Net, получают все преимущества, предоставляемые любым из ваших предпочтительных вариантов, БЕСПЛАТНО. Таким образом, ваше утверждение о том, что XML-файл конфигурации всегда является худшим выбором, не может быть более ошибочным.
Данк
10

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

частота

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

Кто

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

Общая тема

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

тестирование

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


источник
4

Ни частота изменений, ни объем данных не решают, где хранить данные.

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

Конечно, файлы конфигурации, изображения, звуки и т. Д. Обычно лучше хранить в файловой системе.

winkbrace
источник
Я сделал программу помощи call-центра, которая была полностью ориентирована на БД; данные были необходимы для «запуска кода», но было бы абсурдно его компилировать.
DougM
1
Я был разработчиком Oracle в течение 8 лет, но мне все еще не нравятся приложения, которые так тесно связаны с базовой базой данных.
winkbrace
2

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

Алан Б
источник
1

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

Таким образом, вопрос, который вы должны задать, не «как часто это будет меняться?», А «может ли это измениться?». Если значение свойства может изменяться в пределах одной и той же итерации кода (не затрагивая ничего другого в коде) в производственной среде, оно попадает в базу данных.

Thyamarkos
источник
0

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

Если вы храните данные такого рода в базе данных, всегда есть возможность кого-то изменить их на лету и полностью изменить поведение системы.

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

Джеймс Андерсон
источник
0

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

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

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

Кроме того, есть вещи, которые никогда не меняются. Такие вещи, как натуральные константы (G, pi, e, вы называете это), такие вещи, как определенные регулярные выражения, такие как проверка электронной почты.

jwenting
источник