Kiedy jedna rzeczywista wartość danych jest zapisywana w kodzie w przeciwieństwie do korzystania z DB?

17

Od dawna pytanie brzmi: kiedy przechowuję dane (wartości rzeczywiste) w tabeli bazy danych i kiedy przechowuję je bezpośrednio w kodzie?

Niespodziewany konsensus był zazwyczaj taki (*):

Jeśli jest to pojedyncza zmienna, prosta struktura lub tablica kilku wartości, umieść dane bezpośrednio w kodzie.

[* konsensus był dyskutowany w komentarzach i odpowiedziach, ale w zasadzie chciałem mieć jakąś przesłankę, aby szybko rozpocząć pytanie, więc nie krępuj się i popraw go ]

Przykład:

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

Jeśli ma ponad setki wierszy danych tego samego typu, skorzystaj z bazy danych.

Ale wydaje się, że jest szary obszar; co z przypadkami, które nie są tak jasne? Na jakie względy i czynniki należy zwrócić uwagę, aby podjąć decyzję?

Przykład:
Załóżmy, że Twoja firma używa 10-15 różnych typów ram silników, które mogą być reprezentowane jako „412T”. Masz ich około 30 i rzadko się zmieniają. Możesz utworzyć dla nich tabelę DB lub zapisać je na stałe w bazie danych. W tym przypadku silniki są statycznymi, fizycznymi rzeczami, które prawdopodobnie nie będą się często zmieniać.

Trzymanie ich w kodzie poddaje je kontroli źródła, gdzie w bazie danych zmiany DB zwykle nie są śledzone. Ale trzymanie ich w bazie danych uwalnia (oddziela) kod od danych.

Innym (faktycznym) przykładem, którego mogę użyć, jest moje pytanie: /programming/26169751/how-to-best-get-the-data-out-of-a-lookup-table (obecnie 48 wiersze danych opcji).

Dennis
źródło
3
Nieopowiedziana konsensus zwykle NIE był taki: jeśli jest to pojedyncza zmienna lub prosta struktura lub tablica kilku wartości, umieść dane bezpośrednio w kodzie.
Pieter B
Istnieje środkowy sposób: dane są przechowywane w bazie danych. Następnie jest wyodrębniany w celu zapisania kodu źródłowego (np. W global_constants.hpliku).
mouviciel
@mouviciel, ale co stanowi dane ... potrzebujesz danych, aby uzyskać dostęp do bazy danych, więc nie możesz przechowywać w niej wszystkich danych.
jwenting

Odpowiedzi:

33

Nie sądzę, aby te dwa stwierdzenia naprawdę stanowiły konsensus co do tego, kiedy twardo kodować dane:

Jeśli jest to pojedyncza zmienna, prosta struktura lub tablica kilku wartości, umieść dane bezpośrednio w kodzie

Jeśli ma ponad setki wierszy danych tego samego typu, skorzystaj z bazy danych

Prosty kontrprzykład (jestem pewien, że są lepsze): tabele składniowe języka programowania są złożonymi dużymi strukturami, które są często zakodowane na stałe. Spójrz na przykład z kodu źródłowego Perla .

Zamiast tego skupiłbym się najpierw na pytaniu:

  • Jak często zmieniają się dane?

  • Kto może to zmienić?

Jeśli odpowiedź na pytanie „jak często” brzmi „częściej niż chcę wdrożyć nową wersję mojej aplikacji”, to nie powinieneś kodować danych na stałe.

Jeśli odpowiedź na „kto to zmienia” brzmi „ktoś inny niż programista”, to nie powinieneś kodować danych na stałe.

W małym sklepie możliwe jest, że zniknęło rozróżnienie między koderem a użytkownikiem, a także zniknęła idea „wdrożenia”. W takim przypadku jesteś królem własnej domeny i możesz robić, co chcesz.

Ale nawet w takiej sytuacji może pojawić się potrzeba współpracy, co może być trudne, jeśli niestandardowa aplikacja nie przestrzega konwencji, którą zwykle przestrzegają programiści.

kod x
źródło
6
Podobnie do tego, jak często pytanie, innym pytaniem jest: „Jak szybko trzeba to zmienić?” Czynnikiem bramkowania może być czas potrzebny na wdrożenie w całej bazie użytkowników. W przypadku scentralizowanego oprogramowania serwerowego odpowiedź może wynosić kilka minut, ale w przypadku aplikacji mobilnych w terenie może to zająć tygodnie.
CuriousRabbit
W przykładzie Perla powiedziałbym, że an array with a few valueskilka to 377-rzędowe wiersze podstawowego typu danych. Może dla niektórych więcej niż „kilka”, ale wciąż jest dość mały. Mam na stałe podobne, ale nieco mniej płaskie struktury. Jeśli byłby to ponad tysiąc wierszy, prawdopodobnie niechętnie zapisuję go w ten sposób.
Dennis
14

Wybrałbym trzecią opcję: plik konfiguracyjny!

W przypadku aplikacji, nad którymi pracuję (w Javie, więc wszystkie moje przykłady używają Java + Spring), takie wartości są zwykle przechowywane w plikach konfiguracyjnych i wstrzykiwane (przez Spring) do kodu, który ich potrzebuje podczas uruchamiania aplikacji. W pliku właściwości:

motorFramesString=412T, 413T, ...

W konfiguracji wiosennej:

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

Zaletą tego jest to, że możesz łatwo zmienić lub dodać więcej tych najczęściej statycznych wartości, bez ponownej kompilacji, i nie musisz się martwić o wypełnienie (relacyjnej) bazy danych danymi referencyjnymi (ponieważ wydaje się to być troska, a może i tak nie wszystko musi znajdować się w bazie danych).

Co do tego, dlaczego te wartości powinny przejść do pliku konfiguracyjnego zamiast tabeli referencyjnej: Czy planujesz używać tych wartości głównie w kodzie, czy głównie w bazie danych? Jeśli masz wiele istniejących zapytań oraz widoków i procedur, które zależą od tych wartości, najlepiej umieścić je w bazie danych jako dane referencyjne, ponieważ jest to łatwiejsze niż ładowanie ich z plików konfiguracyjnych i wysyłanie ich jako parametrów do każdego możliwego zapytania / widok / procedura, która je odwołuje. Jeśli wartości są najczęściej używane w kodzie aplikacji, plik konfiguracyjny jest prawdopodobnie lepszym wyborem.


Bardziej skomplikowany przykład, taki jak to, co łączysz, można również zrobić z właściwościami lub bez.

W products.properties:

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

W wiosennym pliku konfiguracyjnym:

<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>

Zaletą tego jest to, że jeśli dane źródłowe są arkuszem kalkulacyjnym (jak w pytaniu, do którego prowadzisz link), możesz użyć makr w programie Excel do automatycznego generowania właściwości i fragmentów wiosennych.

FrustratedWithFormsDesigner
źródło
gdy jesteś na przykładzie ramki, jest to dość proste (tylko jedna wartość ciągu). Czy twoje podejście będzie w zasadzie takie samo dla tabeli opcji zawierającej n-krotność zmiennych mieszanych (połączonych na dole mojego pytania)?
Dennis
@Dennis: Dodano bardziej złożony przykład.
FrustratedWithFormsDesigner
8
Plik konfiguracyjny to tylko jedna forma db.
DougM
3
@DougM, zgadzam się, ale istnieje różnica między ustawieniem serii tabel konfiguracji w Oracle a posiadaniem prostego pliku konfiguracyjnego XML. Plik konfiguracyjny ma również tę zaletę, że jest kontrolowany przez kontrolę wersji. Plik konfiguracyjny jest środkiem i zachęca programistów do oddzielenia większej ilości danych konfiguracyjnych. Próbuję wymyślić realistyczne scenariusze, w których nie jest to dobra rzecz
Mcottle,
2
@gbjbaanb: W przypadku większości aplikacji RDBMS to nadmiar umiejętności WAAAAAY, nawet w przypadku dość rozległych systemów. Nie wspominając o tym, że są one powolne i wymagają sporego wysiłku, aby utrzymać i zintegrować się z nimi. Pliki „ini” nie zapewniają żadnego bezpieczeństwa typu, musisz sam napisać parser i musisz napisać własne sprawdzanie typu. Pliki XML Config, przynajmniej w .Net, korzystają z wszystkich zalet jednej z preferowanych opcji zasadniczo ZA DARMO. Zatem twoje twierdzenie, że plik konfiguracyjny XML jest zawsze gorszym wyborem, nie może być bardziej błędne.
Dunk
10

Myślę, że przesłanka pytania nie jest do końca słuszna. Czynnikiem dzielącym nie jest ilość rekordów, które należy zmienić, ale częstotliwość zmian oraz to, kto je zmienia.

Częstotliwość

Kiedy dane są niestabilne , w tym sensie, że często się zmieniają i poza cyklem wydawniczym oprogramowania, muszą być możliwe skonfigurowanie poza zakodowanymi wartościami, a nawet plikami konfiguracyjnymi. Baza danych ma tutaj sens, szczególnie jeśli sama aplikacja jest w stanie ją utrzymać.

Kto

Gdy klient musi mieć możliwość zmiany danych, musi być modyfikowany w sposób przyjazny dla użytkownika i poza cyklem wydania.

Wspólny wątek

Wspólny wątek jest taki, że gdy dane muszą się zmienić poza wersją oprogramowania, powinny być przechowywane w bazie danych. Bazy danych mogą być uaktualniane w trakcie wydania, ale dane pozostają w mocy bez resetowania lub znacznej modyfikacji. Kiedy klient musi mieć możliwość modyfikowania danych (lub konfiguracji funkcjonalności), powinien on być przechowywany w bazie danych z ładnym interfejsem, który jest odporny na idioty.

Testowanie

Pamiętaj, aby napisać testy jednostkowe, które sprawdzą poprawność oprogramowania w różnych konfiguracjach. Być może Twój klient włącza opcjonalny monit lub redefiniuje jeden metr na dwanaście stóp. Bez względu na to, jak rozsądna jest zmiana, jeśli oprogramowanie na to pozwala, cholernie lepiej zweryfikuj, czy zmiana działa zgodnie z oczekiwaniami, bez względu na to, jak szalona jest.


źródło
4

To nie częstotliwość zmian ani ilość danych decyduje, gdzie przechowywać dane.

Jeśli dane są wymagane do uruchomienia programu, jest on częścią kodu programu, więc zapisz go jako stałą. Wszystkie inne dane trafiają do bazy danych.

Oczywiście pliki konfiguracyjne, obrazy, dźwięki itp. Są zwykle lepiej przechowywane w systemie plików.

winkbrace
źródło
Zrobiłem program pomocy call-center, który był całkowicie oparty na db; dane były wymagane do „uruchomienia kodu”, ale skompilowanie go byłoby absurdalne.
DougM
1
Byłem programistą Oracle przez 8 lat, ale nadal nie lubię aplikacji, które mają tak ścisłe połączenie z bazową bazą danych.
winkbrace,
2

Jeśli istnieje jakakolwiek najmniejsza szansa, że ​​kiedykolwiek otrzymasz połączenie telefoniczne, co spowoduje konieczność przebudowania aplikacji, ponieważ zmieniło się coś na stałe, więc nie koduj na stałe. Przynajmniej trzymaj go w pliku konfiguracyjnym lub tabeli db. Nie musisz podawać żadnego interfejsu użytkownika, aby go koniecznie utrzymywać, ale wybranie numeru i zmiana pliku konfiguracyjnego lub uruchomienie aktualizacji SQL na stole jest z pewnością lepszym rozwiązaniem niż przebudowanie całego meczu strzelania.

Alan B.
źródło
1

To rozróżnienie jest rzeczywiście nieco szarym obszarem, ale moje podejście do tego rodzaju problemów brzmi: czy dane zmieniają się w produkcji "? Wszystko, co zmienia się po wdrożeniu w środowisku produkcyjnym, powinno przejść do bazy danych, nawet w przypadku rzeczy, które rzadko mogą się zmienić.

Pytanie, które powinieneś zadać, to nie „jak często to się zmieni?”, Ale „czy to się może zmienić?”. Jeśli wartość właściwości może się różnić w ramach tej samej iteracji kodu (bez dotykania czegokolwiek innego w kodzie) w środowisku produkcyjnym, trafia ona do bazy danych.

Tiamarkos
źródło
0

Brakuje również informacji o typie „kontrola programu”, mówiących, że maksymalny rozmiar bufora, liczba elementów na głos w kolejności, maksymalny rozmiar strony dla ekranu jest zawsze lepiej zakodowany na stałe w programie lub w pliku konfiguracyjnym.

Jeśli przechowujesz tego rodzaju dane w bazie danych, zawsze istnieje możliwość, że ktoś zmieni je w locie i całkowicie zmieni zachowanie systemu.

Innym problemem jest to, że nie ma łatwego sposobu na uzyskanie wpisów w bazie danych za pomocą systemów kontroli źródła / zarządzania zmianami / automatycznych systemów kompilacji, których powinieneś używać.

James Anderson
źródło
0

Jedną rzeczą, której nigdy nie powinieneś przechowywać w bazie danych, są szczegóły potrzebne do uzyskania dostępu do bazy danych.
Jeśli chcesz uzyskać dostęp do bazy danych, aby odzyskać parametry połączenia, nazwę użytkownika i hasło do tej samej bazy danych, masz trochę problemów.

Zaszyfrować to? hmm, może działać, jeśli używasz bazy danych, która instaluje się i jest dostarczana z aplikacją.
Plik konfiguracyjny? Bardziej obiecujące, ale co z bezpieczeństwem konta?

Oczywiście możesz przechowywać informacje o bazie danych w tym pliku konfiguracyjnym w postaci zaszyfrowanej, ale wtedy będziesz musiał gdzieś przechowywać klucze odszyfrowujące, a to prawie na pewno byłoby zapisane na stałe.

Poza tym są rzeczy, które nigdy się nie zmieniają. Rzeczy takie jak stałe naturalne (G, pi, e, jak go nazwiesz), rzeczy takie jak niektóre wyrażenia regularne, takie jak sprawdzanie poprawności wiadomości e-mail.

jwenting
źródło