Найкращий спосіб посилання статичних даних бази даних в код?


24

Багато додатків включають "статичні дані": дані, які насправді не змінюються протягом життя програми. Наприклад, у вас може бути список областей збуту, який, ймовірно, буде фіксованим списком в осяжному майбутньому.

Не рідкість знайти ці статичні дані в таблиці бази даних (часто тому, що ви хочете посилатися на них у зовнішніх ключах інших таблиць). Проста таблиця прикладів матиме Id, який слід використовувати в якості основного ключа та Опис. Наприклад, у таблиці SalesArea буде (принаймні) стовпець SalesAreaId та стовпець SalesAreaDescription.

Тепер у коді ви, можливо, не захочете обробляти кожен рядок таблиці однаково. Наприклад, ви можете встановити зону продажу за замовчуванням на деяких екранах, надати різні цифри для деяких областей або обмежити, що користувачі можуть робити в інших областях.

Який найкращий спосіб посилатися на ці статичні дані в коді? Чому?

  1. Жорстке кодування описів у вашому коді. Використовуйте це, щоб шукати SalesAreaId з бази даних, коли вам це потрібно.
  2. Жорсткий код ідентифікаторів у вашому коді. Використовуйте це, щоб шукати SalesAreaDescription, коли вам це потрібно.
  3. Додайте стовпчик у таблицю для кожної мети, наприклад, стовпець "IsDefaultOnProductLaunchScreen" тощо (їх може бути багато).
  4. Щось ще.

Чи є якісь інші особливі міркування, які я повинен робити, коли маю справу зі статичними даними бази даних? Наприклад, давши цим таблицям спеціальну назву?


1
Можливий дублікат: programmers.stackexchange.com/questions/304169/… Я вважаю, що відповіді на це (зв'язане) потрапляють до суті питання трохи кращого ІМО
JoeCool

Відповіді:


14

Як щодо завантаження їх у кеш (зазвичай реалізується як хеш-таблиця) при запуску програми? Якщо ви це зробите, то вам навіть не потрібно запитувати базу даних (ну, не більше одного разу).

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


Кешування добре, звичайно, але як ви оновлюєте ці значення? Імовірно, перезапуск програми або якась стратегія відключення кешу?
Стів

1
@Steve Так. Залежить від програми. Перезапуск хороший для того, щоб щось почалося часто. Для тривалого запуску програми, можливо, перезавантажуйте кеш-пам'ять один раз на день у повільний час. Моє запитання було б, як щодо сценарію, коли додаток працює дуже багато коротких термінів. Можливо, можливо, сценарій PHP або щось подібне.
tylermac

База даних буде запускати власний кеш для часто доступних даних, тому ви повторно реалізуєте щось, що вже реалізовано (і, мабуть, не так!)
Джеймс Андерсон

@JamesAnderson: Кешування в програмі означає, що коли-небудь буде один виклик до бази даних. Так, у баз даних будуть свої власні кеші, але вони можуть бути визнані недійсними / оновленими подіями, що не перебувають під контролем вашої програми, і вам все одно доведеться підключитися до бази даних та зробити запит, щоб отримати ці дані (і сподіваюся, що вони є в кеш-пам'ять db). Це реально не так складно реалізувати простий кеш в програмі.
FrustratedWithFormsDesigner

7

Альтернативою БД або жорсткому кодуванню є використання конфігураційного файлу, який читається під час запуску. Потім ви можете зберігати ці дані в структурі, що використовується лише для читання, у вашому коді.

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


1
Хороша ідея для деяких типів статичних даних, але не дуже гарна, якщо ви хочете застосувати відносини FK, як описано в питанні.
Відновити Крамію Моніку

Питання не сказав, що це вимога, лише сценарій. Якщо він не потрібен, тоді налаштування файлового файлу працює добре.
Стів

Ви маєте рацію, я був недостатньо зрозумілий. Але я задоволений ... бо я щось дізнався з вашої відповіді. Я ніколи раніше не стикався з таким підходом.
Відновити Крамію Моніку

3

Якщо дані стосуються наявних даних у вашій БД, можливо, настільки ж ефективно їх додати до БД, як і додати їх до коду. Якщо цього не відбувається, я зазвичай спокушаюся "взяти цю кулю один раз" і ввести її в код до першого разу, коли вона зміниться.

Часто те, що, на нашу думку, буде статичним, виявляється не таким, і коли це станеться, вам не потрібно чекати випуску коду, щоб зміни відбулися. Як тільки це станеться один раз, покладіть його в базу даних і напишіть сторінку адміністратора, щоб зробити подальші оновлення.

Для прикладу, якщо у БД вже є сфери продажів, додайте там опис, не створюйте хеш-таблицю, щоб пов’язати дані бази даних із жорстко кодованими списками. Але якщо ви тоді не будуєте хеш-таблицю зон продажів будь-якими способами, але будьте готові, коли перший раз хтось змінить опис або додасть нову зону продажу, перемістіть його в БД.


"Часто те, що ми думаємо, буде статичним, виявляється не так" - так правда.
Відновити Крамію Моніку

3

Чому б просто не важко кодувати все? Основна проблема, яку я завжди мав - це посилання на статичні значення з БД у коді програми. Одна справа, якщо ви просто безпосередньо створюєте випадаючий список або щось із статичних значень, але що робити, якщо якась логіка програми залежить від значень у БД?

У простому додатку в даний час у мене є список держав для редагування вмісту: Чернетка, Опубліковано, Заархівовано.

До елементів вмісту потрібно поводитися по-різному, залежно від того, у якому стані вони перебувають. Якби я зберігав ці дані стану у БД із значеннями 1, 2, 3 відповідно, як би я перейшов до перевірки, чи є щось у Чернетці держава?

if (content.State == 1)
або
if (content.State == "Draft")?

Я просто важко закодував значення!
Те ж саме, якщо ви використовуєте таблицю кешу / хешу: вам все-таки потрібно використовувати якесь значення, записане у вашому коді, як ключ для пошуку даних.

Які недоліки у жорсткого кодування заходу?


Недоліком є, як сказав pdr: "Часто те, що ми вважаємо статичним, виявляється не таким".
tylermac

2
Але якщо ви дійсно посилаєтесь на статичні значення даних у коді, ви не можете змінити їх у базі даних, не порушивши додаток. Напевно, це залежить від того, для чого використовуються дані: як я вже згадував вище, якщо він просто заповнює елемент інтерфейсу, щоб користувач міг вибрати значення та перенести його безпосередньо до БД як частина запису в іншій таблиці , то статичні дані в БД можуть змінюватися незалежно від коду програми. Я впевнений, що така ситуація @pdr говорить: додаток, що обробляє набір статичних даних як єдиний елемент.
Дейв

2

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

Я знаю, що NHibernate ORM пропонує цю функціональність через кеш 2-го рівня . Ви можете сказати, щоб кешувати дані з певної таблиці, і сказати, що це лише для читання. Він буде завантажений перший раз, коли це потрібно, і після цього більше не потраплятиме в базу даних, навіть якщо ви отримуєте доступ до даних з декількох сеансів.


+1 для одного разу та лише одного разу. А як же по-різному ставитися до різних рядків?
Відновити Крамію Моніку

1
@Kramii - Ви можете використовувати щось на кшталт класів перерахунку . Якщо метадані стосуються лише вашої програми, я ставлю бізнес-логіку ( IsDefaultOn...) у властивість сутності. Нехай це повернеться вірно для однієї сутності. Це дозволило б вам знайти цю сутність, враховуючи всю колекцію. Або ви можете використовувати клас контролера, який надасть вам відповідний об'єкт виклику методу.
Скотт Вітлок

2

Це передчасна оптимізація на гірше.

По-перше, будь-яка сучасна СУБД буде отримувати дані з невеликих таблиць з блискавичною швидкістю, і всі вони мають алгоритми кешування, починаючи від хорошого до чудового (чим більше ви заплатили за СУБД, тим краще кешування!). Таким чином, ви оптимізуєте щось, що витрачає мінімальні ресурси.

По-друге, у вас дуже мало досвіду роботи з реальними бізнес-додатками, якщо ви уявляєте щось на зразок "зони продажу" - це статичні дані. Вони можуть змінюватися при кожній зміні директора з маркетингу або генерального директора. Таким чином, ви відправляєтесь у світ болю два роки вниз.

Є лише два способи поїхати сюди: -

Зберігайте його в базі даних та отримуйте доступ до даних за допомогою "звичайного" sql.

Зберігайте його у фантазійному файлі конфігурації XML (можливо, доступ до нього через REST або SOAP), який можна легко редагувати, коли відбувається "стратегічна зміна політики".


1

Це залежить від того, що ви робите з даними. Якщо це список чогось, я зазвичай витягую його в масив. Якщо список повинен зростати в іншій версії, легко просто додати до бази даних та змінити код для обробки додаткових даних у масиві (що може навіть не знадобитися залежно від коду, наприклад, перерахування даних із для циклу, використовуючи верхню межу масиву). Якщо це список налаштувань, я зазвичай кодую такі, як їх зазвичай не так багато, і це простіше і швидше, ніж використання оператора SQL. Якщо це налаштування, яке може змінити користувач, і я хочу зберегти вибір для наступних запусків, я створять таблицю для використання в якості реєстру і просто потягну окремі записи до змінних за потребою.


1

Я знаю, що ця відповідь була прийнята, але я хотів поділитися тим, як ми це зробили в моєму останньому магазині веб-розробок, де ми намагалися максимально скоротити введення / виведення бази даних.

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

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

Ми завжди шукали швидшого часу завантаження. Тому ми вирішили реалізувати якомога більше статичних текстових файлів на стороні сервера. Ми зробили це в стороні віджета адміністратора. Кожного разу при оновленні таблиці бази даних ми регенерували б відповідний статичний текстовий файл. Це дало нам дуже гнучку та швидку обстановку.


0

Моє рішення цього, яке може працювати не у всіх ситуаціях, - прив’язати статичні дані бази до жорстко кодованих enum. Оскільки проблема полягає в тому, що динамічні дані (база даних) прив'язані до статичної логіки (коду), зробіть це прив'язування явним (і вільним), маючи таблицю бази даних, яка асоціюється з enum. Наприклад:

LooseDBCodeBinding (database table)
   ID : Int32 (key)
   Name : String
   HardCodedTypeID : Int32

// in code:
public enum LooseDBCodeBinding
{
   TYPE_1 = 1,
   TYPE_2 = 2,
   TYPE_3 = 3 // etc...
}

Потім напишіть інтерфейс користувача, який дозволяє легко переглядати список LooseDBCodeBindingзаписів та відображати їх у LooseDBCodeBinding enumзначеннях (включаючи підтримку "зламаних" прив'язок). Потім можна запрограмувати навколо enumта створити базу даних навколо ключа таблиці, і саме ця таблиця має знання обох контекстів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.