Czy lepiej jest utworzyć klasy model lub trzymać rodzajowe bazy klasie użytkowej?




Mamy prostą klasę użytkową w domu dla naszych połączeń baz danych (lekkie otoki wokół ADO.NET), ale myślę tworzenia klas dla każdej bazy danych / obiektu. Byłoby mądrą rzeczą, aby to zrobić, czy to tylko korzyści, jeśli używaliśmy pełnej ramy MVC dla ASP.NET?


Więc mamy to:



```
SQLWrapper.GetRecordset(connstr-alias, sql-statement, parameters);
SQLWrapper.GetDataset(connstr-alias, sql-statement, parameters);
SQLWrapper.Execute(connstr-alias, sql-statement, parameters);

```

Myśląc w ten sposób:



```
Person p = Person.get(id);
p.fname = jon;
p.lname = smith;
p.Save();

```

lub do nowego rekordu -



```
Person p = new Person();
p.fname = Jon;
p.lname = Smith;
p.Save();
p.Delete();

```

Byłoby to mądry, czy byłoby przesadą? Widzę korzyści dla ponownego użycia, zmiany bazy i konserwacja / czytelność.
To pytanie jest załadowany, dane Driven Design vs domenie napędzane projektu. Dla każdej aplikacji, która ma dobrą ilość zachowań, a następnie powinny być preferowane domeny Driven Design. Raportowania, lub aplikacje użytkowe wydają się działać lepiej (lub są szybsze rozwijanie) z danych Driven Design.


Co pytasz jest „moja firma powinna dokonać fundamentalnej zmiany w jaki projektujemy naszego kodu”. Jako domena-dziwaka, moja reakcja jelit jest krzyczeć **tak** . Jednak przez prosty charakter Twojego pytania, nie jestem pewien, że w pełni zrozumieć zakres zmian pan proponuje. Myślę, że powinieneś porozmawiać ze swoim zespołem o nim.


Trochę literatury, takich jak [DDD Evana](http://domaindrivendesign.org/books/index.html#DDD_apply) książki lub [wolnego fundamentów ebook](http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx) , a następnie będziesz w stanie lepiej ocenić, w jakim kierunku należy się udać.
<p>byłbym bardzo podejrzliwy wobec jakiegokolwiek zestawu uniwersalnych najlepszych praktyk, ponieważ w większości tych dziedzin diabeł tkwi w szczegółach. to, że informacje są stosunkowo powszechne, nie oznacza, że ​​aplikacja korzysta z danych dokładnie w taki sam sposób, jak inne aplikacje. oznacza to, że twój model danych może być nieco inny.</p><ul> <li>imię i nazwisko: dlaczego przechwytujesz imię? jeśli masz obowiązek przechwycenia pełnego imienia i nazwiska osoby (tj. przygotowujesz dokumenty prawne lub akty urodzenia), prawdopodobnie chcesz dać ludziom więcej miejsca na pisanie niż gdybyś tylko prosił o imię i nazwisko osoby, więc wezwać ich w nowej aplikacji internetowej.</li> <li>adres: co zamierzasz zrobić z adresem? jakie adresy przechowujesz? jeśli przechowujesz adres nieruchomości w stanach zjednoczonych, na której tworzysz hipotekę, prawdopodobnie bardzo zależy ci na uzyskaniu w pełni znormalizowanego adresu, w którym to przypadku model danych prawdopodobnie będzie chciał bardzo blisko pod dowolnym adresem narzędzie normalizacyjne zwraca. jeśli chcesz tylko, aby ludzie mogli wpisać adres w celu dostarczenia produktu, prawdopodobnie wystarczy kilka wierszy tekstu swobodnego. długość linii może zależeć od wymagań dalszych procesów, które wykonują takie czynności jak drukowanie etykiet adresowych.</li> <li>stan: zakładając, że możesz zidentyfikować prawidłowe wartości stanu, prawdopodobnie sensowne jest utworzenie tabeli <code>state</code> i utworzenie relacji klucza obcego między tabelami <code>state</code> i <code>address</code>. ale możliwość zidentyfikowania prawidłowych wartości oznacza, że ​​ograniczasz zestaw prawidłowych adresów przynajmniej do określonego zestawu krajów. to jest w porządku dla wielu stron, ale musisz trochę popracować, aby wesprzeć nowy kraj.</li> <li>miasto: jeśli masz do czynienia z danymi, w których istnieją potencjalnie regulacje na poziomie miasta (tj. w których istnieją różne rodzaje stawek podatkowych, które są stosowane w zależności od miasta), możesz chcieć traktować je podobnie jak państwo i mieć <code>city</code> tabela z prawidłowymi miastami i relacja klucza obcego między tabelami <code>city</code> i <code>address</code>. z drugiej strony, jeśli próbujesz tylko dostarczyć produkt i nie przejmujesz się tym, że masz w tabeli różne wersje tego samego miasta, wystarczy, że użytkownik wprowadzi dowolny tekst. oczywiście, jeśli przechowujesz klucze obce, będziesz mieć sporo pracy, aby upewnić się, że masz wszystkie prawidłowe wartości. ale są produkty, w których chodzi o to, że firma już wykonała tę pracę (tj. bazy danych podatków od sprzedaży).</li> <li>telefon: co robisz z numerami telefonów i dlaczego? niektóre aplikacje będą chciały pobierać numery telefonów w dowolnym formacie, w którym użytkownik zdecyduje się je wprowadzić i zachować to formatowanie dla wszystkich kolejnych zapytań. byłoby to powszechne, jeśli projektujesz osobistą książkę adresową, w której użytkownicy mają własne preferencje dotyczące sposobu przechowywania i wyświetlania numerów telefonów. inne aplikacje chciałyby zignorować wprowadzone formatowanie, wyodrębnić tylko znaki numeryczne, a następnie sformatować dane przy pobieraniu, aby wszystkie numery telefonów miały podobne formatowanie. jeśli prowadzisz działalność dla firm, możesz chcieć wprowadzić oddzielne pole dla użytkowników, aby wprowadzić rozszerzenie. jeśli próbujesz wesprzeć proces połączeń wychodzących, możesz chcieć przechowywać numer kierunkowy i kod kraju w osobnych kolumnach, ponieważ chcesz mieć pewność, że masz okna specyficzne dla strefy czasowej do nawiązywania połączeń z osobami o różnych numerach kierunkowych (tworzenie połączenie z kimś ze wschodniej strefy czasowej o 10 rano będzie znacznie lepsze niż wykonanie tego samego połączenia z kimś w strefie czasowej pacyfiku, gdzie jest 7 rano).</li> <li>płeć: w przypadku wielu aplikacji jest całkowicie rozsądne przechowywanie kodu płci („m” lub „f”) w tabeli. z drugiej strony zdarzają się sytuacje, w których możesz chcieć dodatkowych opcji (inne, interseksualne, transseksualne) lub gdy musisz przechowywać coś takiego jak płeć przy urodzeniu i aktualna płeć.</li> </ul> <p>oprócz innych odpowiedzi ...</p><p> <a href="https://dba.stackexchange.com/questions/1677/is-there-any-good-tool-for-making-database-design-and-prototypes/1678#1678">najpierw przechwytywanie modelu koncepcyjnego</a> powinno określać zakres i wymagania. na tej podstawie możesz uzyskać logiczne i fizyczne modele danych.</p><p>gdy jest to w większości statyczne, masz stabilną bazę danych, na której można zbudować aplikację. jest to sprzeczne z pierwszą opcją.</p><p>twój drugi punkt zakończy się brudną, niemożliwą do utrzymania <em> kulą błota </em>. model danych nigdy nie zostanie naprawiony: jeśli nie zaprojektowałeś go z góry, nie będziesz miał czasu, aby go naprawić przed wysyłką. będziesz zbyt zajęty hakowaniem rzeczy razem.</p><p>nastąpią niewielkie zmiany w schemacie, łączenie lub dzielenie tabel, zmiana relacji itp., ale na zlokalizowanych „wyspach”, a model + podstawowy projekt pozostaną niezmienione.</p> Obie alternatywy, które zostały wskazane ma wady i zalety, decyzja zależy od tego jak to plusy i minusy wpływa na aplikację:



> 
> Pobrać wszystkie wartości z bazy danych przy użyciu zwykłego PHP następnie przechowywać je w zmiennej JavaScript, później szukać sekund rozwijanej listy (jeśli wartość pierwszej rozwijanej liście na zmiany wartości) w zmiennej JavaScript (array).
> 
> 
> 


Plusy:


* Minimalizuje petycje http, trzeba tylko jedną prośbę, aby odzyskać całość danych.
* Minimalizuje kwerenda jest potrzebne w bazie danych, na ogół tylko wykonać jedno zapytanie.


Cons:


* Zwiększa ilość pamięci używanej jeśli masz duże ilości danych.
* Jeśli dane zmienia się nieustannie, użytkownicy nie widzą zmian aż odświeżyć całą stronę.



> 
> Jeśli pierwszy rozwijanej liście zmian wartości jest następnie pobrać wartości dla drugiej listy rozwijanej z bazą danych za pomocą technologii AJAX (jQuery).
> 
> 
> 


Plusy:


* Nie trzeba do przechowywania wszystkich danych w pamięci całych jedynie dane, które zostaną wykorzystane, co zmniejsza ilość potrzebnej pamięci.
* Twoje dane są aktualizowane za każdym razem, bez konieczności przeładowania strony tylko zmieniając wybór.


Cons:


* Trzeba wykonać kilka petycji HTTP i biegnie querys z bazą danych przy każdej zmianie wyboru.


Osobiście preferuję metodę 2, jeśli ilość danych jest stosunkowo duża i wydajność nie jest koniecznością. <p>w większości baz danych a <code>not null</code> kolumna będzie bardziej wydajna pod względem przechowywanych danych z podanego powodu, a także bardziej wydajna w wyszukiwaniu i indeksowaniu - więc jeśli nie chcesz zezwalać na wartości null w kolumnie, powinieneś je wyraźnie zabronić.</p><p>będzie to miało niewielki wpływ na wydajność, ponieważ dodatkowe <code>not null</code> ograniczenia będą potencjalnie musiały być sprawdzane dla każdego wiersza, którego dotyczy zmiana za pomocą insert lub update, ale ponieważ większość baz danych jest względnie łatwa do zapisu i bardzo obciążona odczytem, ​​prawdopodobnie nie stanowi to problemu (mało czasu poświęconego na to jest zauważalne przy w każdym razie, ponieważ jest to operacja związana z procesorem, w której reszta operacji wstawiania/aktualizacji będzie związana z operacjami we/wy, a więc o wiele bardziej znaczącym „wąskim gardłem” i daje pewne „bezpłatne” sprawdzanie danych, więc kod (lub inny) kod osoby) nie może przypadkowo umieścić wartości null tam, gdzie inny kod ich nie oczekuje, a zatem może dawać nieprawidłowe wyniki w ich obecności.</p><p>edycja: jak peter wskazuje w swoim komentarzu, powyższe jest generalizmem i może nie być prawdziwe dla <em>wszystkich</em> dmbs, chociaż jestem prawie pewien, że tak jest w przypadku mysql i mssql. inne komplikacje w tym obszarze mogą obejmować takie funkcje, jak rzadkie tabele (na przykład zaimplementowane mssql 2008), które zmienią dynamikę wydajności (nie) zerowalnych kolumn.</p> <p>josh,</p><p>jest to bardzo częste zadanie dla wszystkich dba i poprawna odpowiedź nie jest taka sama dla każdego i dla każdego serwera. podobnie jak wiele innych rzeczy, zależy to od tego, czego potrzebujesz.</p><p>zdecydowanie nie chcesz uruchamiać „shrink database”, jak już sugerowano. jego zło do wydajności, a poniżej odniesienie pokaże ci dlaczego. powoduje to fragmentację dysku i indeksów, co może prowadzić do problemów z wydajnością. lepiej jest, jeśli wstępnie przydzielisz duży rozmiar danych i plików dziennika, aby automatyczne uruchamianie nie uruchomiło się.</p><p>nie zrozumiałem twojego nr 2. pełna kopia zapasowa wybranych tabel. czy możesz rozwinąć więcej na ten temat?</p><p>przychodząc do reorganizacji indeksu, aktualizacji statystyk i przebudowy indeksu, musisz uważać na to, jak to zrobisz, w przeciwnym razie skończy się to na użyciu większej ilości zasobów, a także na problemach z wydajnością.</p><p>po przebudowaniu indeksów statystyki indeksów są aktualizowane za pomocą fullscan, ale jeśli później zaktualizujesz statystyki, zostaną one ponownie zaktualizowane z domyślną próbką (która zależy od kilku czynników, zwykle 5% tabeli, gdy rozmiar tabeli&gt; 8 mb), co może prowadzić do problemów z wydajnością. w zależności od posiadanej edycji może być możliwe przebudowywanie indeksu online. właściwym sposobem wykonywania tej czynności jest sprawdzenie stopnia fragmentacji i w zależności od tego albo przebuduj indeks, albo zreorganizuj indeks + zaktualizuj statystyki. możesz także określić, które tabele wymagają częstszej aktualizacji statystyk i próbować częściej aktualizować statystyki.</p><p>plany konserwacji są w porządku, ale trudno jest uzyskać z nich jak najwięcej, wykonując te dostosowania, chyba że możesz zalogować się do ssis i poprawić mp. dlatego wolę nie używać ich i używać <a href="https://ola.hallengren.com">darmowe skrypty oli hallengren</a> , które są bardziej niezawodne niż mp. poleciłbym również nadrobić zaległości w artykule paula randala na ten temat.</p><p>ref: <a href="http://technet.microsoft.com/en-us/magazine/2008.08.database.aspx">http://technet.microsoft.com/en-us/magazine/2008.08.08.database.aspx</a> </p><p>to nie jest wyczerpująca odpowiedź na twoje pytanie, ale dobry punkt wyjścia. hth i daj nam znać, jeśli masz dodatkowe pytania/komentarze.</p> <p>po pierwsze, jaki typ modelu bezpieczeństwa planujesz wdrożyć? kontrola dostępu oparta na rolach (rbac) czy dyskrecjonalna kontrola dostępu (dac)?</p><blockquote> <p>rbac w modelu kontroli dostępu opartej na rolach (rbac) dostęp do zasobów zależy od roli przypisanej użytkownikowi. w tym modelu administrator przypisuje użytkownika do roli, która ma pewne określone prawa i uprawnienia. ze względu na powiązanie użytkownika z rolą użytkownik może uzyskać dostęp do niektórych zasobów i wykonywać określone zadania. rbac jest również znany jako niedyskrecjonalna kontrola dostępu. role przypisane do użytkowników są administrowane centralnie.</p> <p>dac w modelu dyskretnej kontroli dostępu (dac) dostęp do zasobów zależy od tożsamości użytkownika. użytkownik otrzymuje uprawnienia do zasobu poprzez umieszczenie go na liście kontroli dostępu (acl) powiązanej z zasobem. wpis na liście acl zasobu jest znany jako wpis kontroli dostępu (ace). gdy użytkownik (lub grupa) jest właścicielem obiektu w modelu dac, użytkownik może udzielić uprawnienia innym użytkownikom i grupom. model dac opiera się na własności zasobów.</p> </blockquote><p> <a href="http://www.webune.com/forums/differences-between-mac-dac-and-rbac.html">patrz źródło</a> </p><p>1) w rbac: potrzebujesz tabeli elementtype, aby przypisać prawa do roli (użytkownicy są przypisani do ról). rbac definiuje: „co może zrobić ta rola/użytkownik”. administrator przypisuje prawa do ról i uprawnienia do ról, przypisuje użytkowników do ról w celu uzyskania dostępu do zasobów. 2) w dac: użytkownicy i role mają prawa do elementów poprzez listę kontroli dostępu (własność). dac definiuje: „kto ma dostęp do moich danych”. użytkownik (właściciel) udziela uprawnień do posiadanego zasobu.</p><p>w dowolny sposób sugeruję ten model danych:</p><pre><code>create table elementtype ( id (pk) name ... ) create table elementbase ( id (pk) type (fk to elementtype) ... ) </code></pre><p>(relacja jeden do jednego)</p><pre><code>create table element\_a ( id (pk, fk to elementbase) ... ) create table element\_b ( id (pk, fk to elementbase) ... ) </code></pre><p>1) rbac (relacja wiele do wielu)</p><pre><code>create table elementtype\_to\_role\_rights ( rightid (pk) roleid (fk to role) elementtypeid (fk to elementtype) ... ) </code></pre><p>2) dac (relacja wiele do wielu)</p><pre><code>create table elementbase\_to\_actor\_rights ( rightid (pk) elementbaseid (fk to elementbase) actorid (fk to actor) ... ) create table actor ( id (pk) name ) create table user ( id (pk, fk to actor) password ... ) create table role ( id (pk, fk to actor) ... ) </code></pre> <p>w witrynach, w których pracowałem, wszelkie zmiany, które należy wprowadzić w instancjach produkcyjnych, muszą być skryptowane jako skrypty zmian, które będą działać w sql * plus; ponadto skrypty potrzebne do odtworzenia od podstaw wszystkich obiektów schematu muszą być aktualizowane. wszystkie te skrypty są sprawdzane pod kątem kontroli zmian i stamtąd migrowane.</p><p>możesz kontrolować zmiany ddl lub używać wyzwalaczy ddl, aby wykrywać zmiany, a nawet używać oprogramowania różnicowego do porównywania dwóch wystąpień, ale metody te są niedyskryminujące; często programista wprowadza i cofa wiele zmian w schemacie (np. małe zmiany testowe, tworzenie fałszywych tabel do testowania koncepcji itp.) przed ustaleniem, co dokładnie należy zmienić.</p> <p>ma więcej kolumn niż pokaż status tabeli; ale robi sztuczkę:</p><pre><code>select * from information\_schema.tables where table\_schema = database(); </code></pre><p>aktualizacja 2011-06-07 19:02</p><pre><code>select table\_name,engine,version,row\_format,table\_rows,avg\_row\_length, data\_length,max\_data\_length,index\_length,data\_free,auto\_increment, create\_time,update\_time,check\_time,table\_collation,checksum, create\_options,table\_comment from information\_schema.tables where table\_schema = database(); </code></pre><p>te zapytania działają, jeśli ustawisz bieżącą bazę danych.</p><p>możesz także kodować konkretną bazę danych:</p><pre><code>select table\_name,engine,version,row\_format,table\_rows,avg\_row\_length, data\_length,max\_data\_length,index\_length,data\_free,auto\_increment, create\_time,update\_time,check\_time,table\_collation,checksum, create\_options,table\_comment from information\_schema.tables where table\_schema = 'mysql'; </code></pre> <p>od <a href="http://msdn.microsoft.com/en-us/library/ms188029.aspx">books online</a> </p><blockquote> <p>format nowej\_tabeli określa się, oceniając wyrażenia na liście wyboru. kolumny w nowej\_tabeli są tworzone w kolejności określonej przez listę wyboru. każda kolumna w tabeli nowa\_ ma taką samą nazwę, typ danych, dopuszczalność nullab i wartość jak odpowiednie wyrażenie na liście wyboru. <strong> właściwość tożsamość kolumny jest przenoszona </strong>, z wyjątkiem warunków określonych w „praca z kolumnami tożsamości” w sekcji uwagi.</p> </blockquote><p>w dół strony:</p><blockquote> <p>po wybraniu istniejącej kolumny tożsamości do nowej tabeli nowa kolumna dziedziczy właściwość tożsamość, chyba że spełniony jest jeden z następujących warunków:</p> <ul> <li>instrukcja select zawiera funkcję join, group by lub funkcję agregującą.</li> <li>wiele instrukcji select jest łączonych za pomocą union.</li> <li>kolumna tożsamości znajduje się na liście wyboru więcej niż jeden raz.</li> <li>kolumna tożsamości jest częścią wyrażenia.</li> <li>kolumna tożsamości pochodzi ze zdalnego źródła danych.</li> </ul> <p>jeśli którykolwiek z tych warunków jest spełniony, kolumna jest tworzona nie null zamiast dziedziczenia właściwości tożsamość. jeśli w nowej tabeli wymagana jest kolumna tożsamości, ale taka kolumna nie jest dostępna lub chcesz mieć wartość początkową lub przyrostową inną niż kolumna tożsamości źródłowej, zdefiniuj kolumnę na liście wyboru za pomocą funkcji tożsamość. zobacz „tworzenie kolumny tożsamości za pomocą funkcji tożsamość” w sekcji przykłady poniżej.</p> </blockquote><p>więc ... teoretycznie można uciec:</p><pre><code>select id, val into copy\_from\_with\_id\_2 from with\_id union all select 0, 'test\_row' where 1 = 0; </code></pre><p>ważne byłoby skomentowanie tego kodu, aby go wyjaśnić, aby nie został usunięty następnym razem, gdy ktoś na niego spojrzy.</p> Nazwa je takimi, jakimi są.


Jeśli nazywanie ich jest trudne lub niejednoznaczne, często jest to znak, że Klasa robi zbyt wiele (Zasada Odpowiedzialności Pojedynczej).


Aby uniknąć konfliktów nazw, należy odpowiednio wybrać przestrzeń nazw.


Personnally, użyję 3