eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.pecetSerwer dla MS-SQL (crosspost) › Re: Serwer dla MS-SQL (crosspost)
  • Path: news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.
    atman.pl!news.nask.pl!news.nask.org.pl!news.interia.pl!not-for-mail
    From: Adam <a...@p...onet.pl>
    Newsgroups: pl.comp.os.ms-windows.winnt,pl.comp.pecet
    Subject: Re: Serwer dla MS-SQL (crosspost)
    Date: Sat, 19 Apr 2014 22:11:50 +0200
    Organization: INTERIA.PL S.A.
    Lines: 283
    Message-ID: <liula7$jvg$1@usenet.news.interia.pl>
    References: <lir1o7$rq5$2@usenet.news.interia.pl>
    <53511928$0$2153$65785112@news.neostrada.pl>
    <lir8no$anp$1@usenet.news.interia.pl>
    <53516316$0$2233$65785112@news.neostrada.pl>
    <litnm7$l45$1@usenet.news.interia.pl>
    <53527a63$0$2241$65785112@news.neostrada.pl>
    <liua3i$s0u$1@usenet.news.interia.pl>
    <5352c885$0$2366$65785112@news.neostrada.pl>
    NNTP-Posting-Host: ent22.internetdsl.tpnet.pl
    Mime-Version: 1.0
    Content-Type: text/plain; charset=UTF-8; format=flowed
    Content-Transfer-Encoding: 8bit
    X-Trace: usenet.news.interia.pl 1397938312 20464 83.15.205.22 (19 Apr 2014 20:11:52
    GMT)
    X-Complaints-To: u...@f...interia.pl
    NNTP-Posting-Date: Sat, 19 Apr 2014 20:11:52 +0000 (UTC)
    User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:24.0) Gecko/20100101 Thunderbird/24.4.0
    In-Reply-To: <5352c885$0$2366$65785112@news.neostrada.pl>
    Xref: news-archive.icm.edu.pl pl.comp.os.ms-windows.winnt:252594
    pl.comp.pecet:1235231
    [ ukryj nagłówki ]

    W dniu 2014-04-19 21:03, wloochacz pisze:
    > W dniu 2014-04-19 19:00, Adam pisze:
    >> (...)
    >>>> Ale to jeszcze o niczym nie świadczy.
    >>>> Widziałem (nie pamiętam, gdzie) pola typu DECIMAL(15,2) używane do
    >>>> przechowywania flagi, gdzie wystarczyłoby pole SMALLINT.
    >>> Wystarczyłoby - a i pewnie, ale tak się nie projektuje dużego systemu.
    >>> Najpierw definiujesz sobie własne typy danych (domneny), a potem ich
    >>> używasz. jakbym miał w kazdym polu każdej tabeli okreslać typ i rozmiar
    >>> to by mnie k...wica strzeliła bardzo szybko :)
    >>
    >> Nie rozumiem.
    >> Wydawało mi się, że definiując tabelę w SQL, należy też zdefiniować
    >> poszczególne pola, czyli przykładowo:
    > Oczywiście, że pola trzeba zdefiniować - pisałem o typach danych
    > (domenach, czyli wg terminologii MSSQL "User-Definied Data Types");
    > Spójrz - w tym przykładzie definicja tabeli jest oparta na standardowych
    > typach danych i OK.
    > Ale...
    >
    >> CREATE TABLE [CDN].[TraNag](
    >> [TrN_TrNID] [int] IDENTITY(1,1) NOT NULL,
    >> [TrN_RelTrNId] [int] NULL,
    >> [TrN_FVMarza] [tinyint] NULL,
    >> [TrN_DDfId] [int] NULL,
    >> [TrN_TypDokumentu] [int] NOT NULL,
    >> [TrN_ZwrId] [int] NULL,
    >> [TrN_ZwrIdWZKK] [int] NULL,
    >> [TrN_FaId] [int] NULL,
    >> [TrN_NumerNr] [int] NOT NULL,
    >> [TrN_NumerString] [varchar](31) NOT NULL,
    >>
    >> itd.
    > Moja tabela wygląda np. tak:
    > CREATE TABLE [dbo].[tDfLogEntity]
    > (
    > [IdEntity] [dbo].[uNAME_L] NOT NULL,
    > [PkValue] [dbo].[uNAME_M] NOT NULL,
    > [IdUser] [dbo].[uINT] NOT NULL,
    > [LogType] [char] [uName_S] NOT NULL,
    > [LogDate] [dbo].[uDATE_TIME] NOT NULL,
    > [UpdateCount] [dbo].[uINT_BIG] NOT NULL
    > )
    > Np. definicja domnety uNAME_L wygląda tak:
    > CREATE TYPE [dbo].[uNAME_L] FROM [varchar](80) NULL
    >
    > I potem posługujesz się wszedzie własnymi typami, nie muszisz się
    > zastanawiać czy to był varchar(80) czy 180...
    > To po prostu wygodne i łatwe do utrzymania.
    >
    Z Twojego punktu widzenia - może to być czytelne.
    Ale z punktu widzenia producenta programu - chyba niekoniecznie.
    Jeśli ktoś wypuszcza program "do ludzi", to wydaje mi się, że lepiej
    jest, aby typy były typowe ;)

    _Management_Studio_ pokazuje (dla TraNag):

    CREATE TABLE [CDN].[TraNag](
    [TrN_TrNID] [int] IDENTITY(1,1) NOT NULL,
    [TrN_TerminZwrotuKaucji] [datetime] NULL,
    [TrN_OFFPrawoDoFAPA] [tinyint] NULL,
    [TrN_OFFPrawoDoAnulowania] [tinyint] NULL,
    [TrN_RelTrNId] [int] NULL,
    [TrN_FVMarza] [tinyint] NULL,
    [TrN_DDfId] [int] NULL,
    [TrN_TypDokumentu] [int] NOT NULL,
    [TrN_ZwrId] [int] NULL,
    [TrN_FaId] [int] NULL,
    [TrN_NumerNr] [int] NOT NULL,
    [TrN_NumerString] [varchar](31) NOT NULL,
    [TrN_Bufor] [smallint] NOT NULL,
    [TrN_Anulowany] [int] NOT NULL,
    [TrN_VaNId] [int] NULL,
    [TrN_DataDok] [datetime] NOT NULL,
    [TrN_DataWys] [datetime] NOT NULL,
    [TrN_DataOpe] [datetime] NOT NULL,
    [TrN_NumerObcy] [varchar](30) NOT NULL,
    (...)

    _Dokumentacja_ pokazuje:

    Nazwa // Typ // Opis // Opcje
    TrN_TrNID // INTEGER // Identyfikator rekordu // Unikalny identyfikator
    rekordu. Poprzez to pole realizowane są wszystkie relacje typu 1:MANY do
    innych tabel. // IDENTITY(1,1)

    TrN_RelTrNId // INTEGER// Pomocnicze pole relacji miedzy dokumentami

    TrN_FVMarza // TINYINT // Faktura marza 1 - Faktura marza

    TrN_FVMarzaRodzaj // TINYINT // Faktura marza rodzaj 1- Procedura marży
    dla biur podróży 2- Procedura marży - towary używane 3- Procedura marży
    - dzieła sztuki 4- Procedura marży - przedmioty kolekcjonerskie i antyki

    TrN_DDfId // INTEGER // Identyfikator dokumentu w tabeli DokDefinicje

    TrN_TypDokumentu // INTEGER // Typ dokumentu (klasa dokumentu z tabeli
    DokDefinicje) // NOT NULL

    TrN_ZwrId // INTEGER // Identyfikator dokumentu źrodlowego dla
    dokumentów korygujących

    TrN_ZwrIdWZKK // INTEGER // Identyfikator dokumentu źrodlowego dla
    dokumentów korygujących WZKK

    TrN_FaId // INTEGER // Wskaźnik do faktury wykorzystywany przy
    przekształacaniu paragonów i WZ do faktury W paragonie lub WZ jest tu
    TrNId faktury, do której został przekształcony dokument źródłowy

    TrN_NumerNr // INTEGER // Autonumerowany czlon numeru dokumentu // NOT
    NULL

    TrN_NumerString // VARCHAR(31) Stały (parametryzowalny) człon numeru
    dokumentu // NOT NULL

    TrN_NumerPelny // COMPUTED|VARCHAR(30) Pełny numer dokumentu Numer
    wyliczany funkcją serwerową //
    CDN.FN_NUMERPELNY(TRN_NUMERNR,TRN_NUMERSTRING)

    TrN_Bufor // SMALLINT // Stan dokumentu 1 - bufor,
    0 - zatwierdzony, -1 - anulowany // NOT NULL
    (...)

    itd., później opisy kluczy i relacji.
    Oczywiście wszystko tabelarycznie, tutaj próbowałem to "przełożyć" na
    "płaski" txt.

    Wydaje mi się (przy aktualnym stanie mojej wiedzy), że gdyby ktoś dostał
    dokumentację z nadanymi własnymi, nietypowymi nazwami typów danych, to
    musiałby dostać jeszcze "słownik" owych typów - dodatkowa niepotrzebna
    translacja ;)


    > Poza tym mam własne rpzmyślenia na nazywanie table, procedur, pól itd w
    > bazie danych. To co jest w CDN mi się nie podoba; uważam za zbyteczne
    > dodowanie przedrostka do nazwy pola, który określa z jakiej jest tabeli.
    > Po co to? Przecież od tego są aliasy, czyli:
    > select H.TrN_ZwrTyp,
    > H.TrN_ZwrFirma,
    > H.TrN_ZwrNumer,
    > L.TrE_JmFormatZ,
    > L.TrE_TypJm,
    > L.TrE_PrzeliczM,
    > L.TrE_PrzeliczL,
    > L.TrE_GrupaPod
    > from CDN.TraNag H
    > inner join CDN.TraElem L on (L.TrE_GIDNumer = H.TrN_GIDNumer)
    >

    Aliasy są wykorzystywane.

    > U mnie każde pole nazywa się dokładnie tak samo w każdej tabeli, jeśli
    > niesie tę samą informację logiczną (np. kod klienta, nr dokumentu,
    > itd.). Ale to wynika też z pewnych mechanizmów w programowaniu
    > apliakcji, ale to już zupełnie inna bajka...

    Tutaj chyba też:

    Tabele TraNag (1:MANY) TraElem
    Pola łączące TrN_TrNID = TrE_TrNId
    Opcje Klucz obcy FK_TrETraNag


    > (...)
    >>> Używanie triggerów do zapewnienia integralności referencyjnej jest, moim
    >>> zdaniem, błędem. Jest tylko jeden przypadek, kiedy trzeba użyć takiego
    >>> mechanizmu w MSSQL - ale to wyjątek od reguły.
    >>
    >> Optima jest (była?) pomyślana jako system "strojony" pod klienta.
    >> Naprawą baz w założeniu mieli się zajmować serwisanci o różnym stopniu
    >> wiedzy.
    > W dobrze zaprojektowanej i wdrożonej aplikacji (i bazie danych
    > oczywiście) nie ma prawa zdarzyć się coś takiego jak "popsuta baza".
    > Nie wiem, może za mało widziałem, ale... Zajmuję się MSSQLem od wersji
    > 2000 na poważnie i nigdy nie miałem przypadku popsutej bazy danych, na
    > poziomie serwera.
    > Braki w danych, osercone dokumenty, zagubione transkacje - pewnie, że
    > było. Ale to był efekt źle zaprojektowanej apliakcji. Tylko i wyłącznie.

    Nie wiem, czy dobrze się wyraziłem.

    Przykład:
    Klient się "walnął" i z jakichś powodów trzeba fakturę wycować "do
    bufora" ("Bufor" oznacza, że dokument jest zapisany, ale nie
    zatwierdzony "na stałe", można go dowolnie zmieniać lub usunąć).

    Przy wycofaniu do bufora trzeba pamiętać, aby wycofać dokumenty
    magazynowe (czyli WZ), wycofać płatności (czyli KP), wrócić ewentualne
    rezerwacje i jeszcze wiele innych rzeczy.
    Wydaje mi się, że gdyby nie było triggerów, to serwisant mógłby
    przykładowo wycofać WZ, przywrócić rezerwacje, ale zapomniałby o
    wycofaniu płatności.

    Tym zajmują się triggery.

    Czy dobrze myślę?


    >> Stąd też np. przy kasowaniu rekordu (bezpośrednio w bazie danych) w
    >> TraNag (nagłówku transakcji) sprawdzane są najprzeróżniejsze warunki,
    >> takie jak rezerwacje, płatności, stany na poszczególnych magazynach i
    >> całe mnóstwo innych. Stąd ktoś (nawet przypadkowy), kto "dobierze się"
    >> do bazy danych SQL nawet prostym skanerem, nie jest w stanie jej zepsuć.
    >> No, chyba że zna polecenie:
    >> Alter table cdn.JakasTabela disable trigger all
    > Po pierwsze - nikt normalny nie daje bezpośredniego dostępu do bazy
    > danych. To jak gmeranie w nosie odbezpieczonym granatem.
    > Robiłem takie cuda, jasne - alke to wymaga perfekcyjnej znajomości
    > logiki aplikacji i mechanizmów bazy danych. Jak nie popsujesz coś w
    > danych, to mozesz spowodować eskalację blokad - na przykład.
    >
    >> Czasami zdarza się go używać, ostatnio np. musiałem zmienić definicję
    >> numeracji kasy na "żywym" raporcie kasowym z SYMBOL/NR/ROK na
    >> SYMBOL/NR/KASA/ROK czy jakoś tak.
    >>
    >> Tak więc z mojego punktu widzenia trigger jest co najmniej pomocny, żeby
    >> nie powiedzieć niezbędny. Ale być może czegoś nie wiem.
    > :-)
    > Nie obraź się, ale właśnie zacytowałeś mi standardową regułkę
    > producenta, który musi jakoś przekonać innych do swojego rozwiązania.
    > Ale ja tego nie kupuję ;-)
    > Więcej - mam wyrobione zdanie na ten temat poparte doświadczeniem gdzie
    > było mniej więcej podobnie. I nigdy więcej!
    > Tj. spora część logiki była zaszyta w bazie danych, ale to nie było
    > dobre. Moje doświadczenia to nie tylko wdrażanie, ale też rozwój i
    > utrzymanie tak napisanej aplikacji.

    Ale jeśli utrzymaniem aplikacji zajmuje się cały tabun studentów?

    Jeśli dodatkowe funkcje (i triggery, i coś tam jeszcze) dopisuje
    "tysiąc" dystrybutorów i dealerów?


    >
    > Dlaczego uważam to za niezbyt szczęśliwe rozwiązanie? Po pierwsze i
    > najważniejsze - rozproszona odpowiedzialność (nie wiem czy programujesz,
    > ale zapoznaj się z zasadą SOLID a ja tu piszę o pierwszej z nich, czyli
    > "single responsibility").

    No właśnie.
    Niedouczony serwisant nie da rady "zbuforować" przykładowej faktury, nie
    robiąc całego ciągu zdarzeń z tym związanego. Albo spełni wszystkie
    warunki, aby móc zbuforować fakturę, albo trigger poinformuje go, że
    zapomniał wycofać płatność.


    > Nie do końca wiadomo co robi aplikacja (i dlaczego), a co robi baza (i
    > dlaczego). Ja chcę mieć spokój i uważam, że aplikacja powinna być
    > wygodna w rozwouju i elastyczna w dostosowaniu.
    > Od tej pory minimalizuję logikę w bazie do minimum - de-facto poza
    > utrzymaniem integralności więcej logiki tam nie ma.
    > Tak, tak - wiem - to taki święty Graal aplikacji biznesowych ;-)
    >
    >> Nie wyobrażam sobie "gmerania" na bazie danych z
    >> kilkudziesięciostronicowym materiałem opisującym jakieś zależności czy
    >> uwarunkowania.
    > Tyle to pikuś :D
    > Co powiesz na to; ok. 1100 tabel i 12 tyś procedur? Oczywiście zero
    > dokumentacji technicznej - tylko aplikacja i profiler.
    > I weź w tym gmeraj ;-)
    >

    Można się załamać :(

    Ja tak uczyłem się wieki temu pisać w Clarionie 2.1 for DOS - widziałem
    aplikację, miałem szczątek dokumentacji po angielsku (a wtedy znałem
    może kilkadziesiąt słow po angielsku) i widziałem, co aplikacja robi.
    Próbowałem to powtórzyć.
    Dopiero jakieś 3 lata później ktoś napisał podręcznik w jęz. polskim.
    Napisał zresztą 2 tomy, ale jak z nim rozmawiałem, to drugiego nie udało
    się wydać.
    Internetu jeszcze nie było, tylko Fido i BBS-y.




    Ale pogadamy może nieco później - Wesołych Świąt :)


    --
    Pozdrawiam.

    Adam

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: