Jak dokumentujesz swoje bazy danych?


227

Uważam, że większość moich klientów w ogóle nie dokumentuje swoich baz danych i wydaje mi się to dość przerażające. Aby wprowadzić jakąś lepszą praktykę, chciałbym wiedzieć, jakich narzędzi / procesów używają ludzie.

  • Jak dokumentujesz swoją bazę danych? (SQL-Server)
  • Jakiego narzędzia używasz?
  • Format przechowywania dokumentacji dla schematu / metadanych bazy danych?
    • Dokumenty Word
    • Excel arkusz kalkulacyjny
    • Zwykły tekst
  • Proces dokumentacji lub zasady?

Nie mówię o inżynierii odwrotnej / dokumentowaniu istniejącej bazy danych, ale głównie o najlepszych praktykach dokumentacji podczas tworzenia systemu / bazy danych.

Odpowiedzi:


78

Korzystam z rozszerzonych właściwości, ponieważ są one bardzo elastyczne. Większość standardowych narzędzi do dokumentacji można wyłączyć MS_Description, a następnie można użyć własnych z narzędziami niestandardowymi.

Zobacz tę prezentację: # 41-Zdobądź dźwignię i wybierz dowolnego żółwia: podnoszenie za pomocą metadanych

I ten kod: http://code.google.com/p/caderoux/wiki/LeversAndTurtles


3
Możesz coś zmienić i zapomnieć odpowiednio zmienić swoje rozszerzone właściwości, czyniąc je niepoprawnymi. Czy potrafisz automatycznie wykryć takie rozbieżności?
AK

2
Można przynajmniej zapytać o schemat bazy danych (sys.tables / sys.columns) i pozostawić dołączenie do jego rozszerzonych właściwości (sys.extended_properties) w celu zidentyfikowania nieudokumentowanych pól, a następnie przekształcić ten skrypt w test, który ma zostać uruchomiony podczas wdrażania.
Micheasza

59

Microsoft Visio Pro (do Visio 2010) może dokonywać inżynierii wstecznej bazy danych, podobnie jak ERwin urzędu certyfikacji . Visio jest tańszą opcją, ale ERwin jest bardziej szczegółową i kompletną opcją. Rozszerzone właściwości są miłe, jeśli ludzie próbują na nie spojrzeć. Możesz także użyć czegoś takiego jak dokument SQL firmy Red Gate do generowania dokumentacji w formacie HTML.

Uważam, że konwencje nazewnictwa i prawidłowe konfigurowanie kluczy obcych prowadzą do prawie samodokumentującej się bazy danych. Nadal powinieneś mieć jakieś zewnętrzne dokumenty, aby lepiej zrozumieć cel.


To, czego często brakuje w prostym schemacie (nawet w dobrze nazwanej i obcej bazie danych), to opisy pól. Z mojego doświadczenia wynika, że ​​wszystkie pola są na tyle proste, aby pasowały do ​​nazwy kolumny.
StockB


26

W przypadku SQL Server używam rozszerzonych właściwości.

Za pomocą następującego skryptu PowerShell mogę wygenerować skrypty tworzenia tabeli dla pojedynczej tabeli lub dla wszystkich tabel w schemacie dbo.

Skrypt zawiera Create tablepolecenie, klucze podstawowe i indeksy. Klucze obce są dodawane jako komentarze. Rozszerzone właściwości tabel i kolumn tabeli są dodawane jako komentarze. Tak, obsługiwane są właściwości wielu linii.

Skrypt jest dostosowany do mojego osobistego stylu kodowania.

  • brak pojedynczych zestawień dla pojedynczych kolumn.

  • obecnie wymaga uwierzytelnienia serwera Sql.

Oto kompletny kod, który przekształca rozszerzone właściwości w dobry, zwykły stary dokument ASCII (BTW to jest poprawne sql do odtworzenia twoich tabel):

function Get-ScriptForTable
{
    param (
        $server, 
        $dbname,
        $user,
        $password,
        $filter
    )

[System.reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")  | out-null

$conn = new-object "Microsoft.SqlServer.Management.Common.ServerConnection" 
$conn.ServerInstance = $server
$conn.LoginSecure = $false
$conn.Login = $user
$conn.Password = $password
$conn.ConnectAsUser = $false
$srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $conn

$Scripter = new-object ("Microsoft.SqlServer.Management.Smo.Scripter")
#$Scripter.Options.DriAll = $false
$Scripter.Options.NoCollation = $True
$Scripter.Options.NoFileGroup = $true
$scripter.Options.DriAll = $True
$Scripter.Options.IncludeIfNotExists = $False
$Scripter.Options.ExtendedProperties = $false
$Scripter.Server = $srv

$database = $srv.databases[$dbname]
$obj = $database.tables

$cnt = 1
$obj | % {

    if (! $filter -or  $_.Name -match $filter)
    {
        $lines = @()
        $header = "---------- {0, 3} {1, -30} ----------"  -f $cnt, $_.Name
        Write-Host $header 

        "/* ----------------- {0, 3} {1, -30} -----------------"  -f $cnt, $_.Name
        foreach( $i in $_.ExtendedProperties)
        {
            "{0}: {1}" -f $i.Name, $i.value
        }
        ""
        $colinfo = @{}
        foreach( $i in $_.columns)
        {
            $info = ""
            foreach ($ep in $i.ExtendedProperties)
            {
                if ($ep.value -match "`n")
                {
                    "----- Column: {0}  {1} -----" -f $i.name, $ep.name
                    $ep.value
                }
                else
                {
                    $info += "{0}:{1}  " -f $ep.name, $ep.value
                }
            }
            if ($info)
            {
                $colinfo[$i.name] =  $info
            }
        }
        ""
        "SELECT COUNT(*) FROM {0}" -f $_.Name
        "SELECT * FROM {0} ORDER BY 1" -f $_.Name
        "--------------------- {0, 3} {1, -30} ----------------- */" -f $cnt, $_.Name
        ""
        $raw = $Scripter.Script($_)
        #Write-host $raw
        $cont = 0
        $skip = $false 
        foreach ($line in $raw -split "\r\n")
        {
            if ($cont -gt 0)
            {
                if ($line -match "^\)WITH ")
                {
                    $line = ")"
                }
                $linebuf += ' ' + $line -replace " ASC", ""
                $cont--
                if ($cont -gt 0) { continue }
            }
            elseif ($line -match "^ CONSTRAINT ")
            {
                $cont = 3
                $linebuf = $line
                continue
            }
            elseif ($line -match "^UNIQUE ")
            {
                $cont = 3
                $linebuf = $line
                $skip = $true
                continue
            }
            elseif ($line -match "^ALTER TABLE.*WITH CHECK ")
            {
                $cont = 1
                $linebuf = "-- " + $line
                continue
            }
            elseif ($line -match "^ALTER TABLE.* CHECK ")
            {
                continue
            }
            else
            {
                $linebuf = $line
            }
            if ($linebuf -notmatch "^SET ")
            {
                if ($linebuf -match "^\)WITH ")
                {
                    $lines += ")"
                }
                elseif ($skip)
                {
                    $skip = $false
                }
                elseif ($linebuf -notmatch "^\s*$")
                {
                    $linebuf = $linebuf -replace "\]|\[", ""
                    $comment = $colinfo[($linebuf.Trim() -split " ")[0]]
                    if ($comment) { $comment = ' -- ' + $comment }
                    $lines += $linebuf + $comment
                }
            }
        }
        $lines += "go"
        $lines += ""
        $block = $lines -join "`r`n"
        $block
        $cnt++
        $used = $false
        foreach( $i in $_.Indexes)
        {
            $out = ''
            $raw = $Scripter.Script($i)
            #Write-host $raw
            foreach ($line in $raw -split "\r\n")
            {
                if ($line -match "^\)WITH ")
                {
                    $out += ")"
                }
                elseif ($line -match "^ALTER TABLE.* PRIMARY KEY")
                {
                    break
                }
                elseif ($line -match "^ALTER TABLE.* ADD UNIQUE")
                {
                    $out += $line -replace "\]|\[", "" -replace " NONCLUSTERED", "" 
                }
                elseif ($line -notmatch "^\s*$")
                {
                    $out += $line -replace "\]|\[", "" -replace "^\s*", "" `
                    -replace " ASC,", ", " -replace " ASC$", "" `
                    <#-replace "\bdbo\.\b", "" #> `
                    -replace " NONCLUSTERED", "" 
                }
                $used = $true
            }
            $block = "$out;`r`ngo`r`n"
            $out
        }
        if ($used)
        {
            "go"
        }
    }
} 
}

Możesz albo wykonać skrypt pełnego schematu dbo dla danej bazy danych

Get-ScriptForTable 'localhost'  'MyDB' 'sa' 'toipsecret'  |  Out-File  "C:\temp\Create_commented_tables.sql"

Lub filtruj dla pojedynczego stołu

Get-ScriptForTable 'localhost'  'MyDB' 'sa' 'toipsecret' 'OnlyThisTable'

21

Spójrz na SchemaCrawler - to moje darmowe narzędzie wiersza poleceń, które zaprojektowałem, aby robić to, czego szukasz. SchemaCrawler tworzy plik tekstowy ze wszystkimi obiektami schematu bazy danych. Ten tekst wyjściowy został zaprojektowany tak, aby był czytelny dla człowieka, a także odróżniał się od podobnych danych wyjściowych z innego serwera.

W praktyce odkryłem, że wyjście pliku tekstowego schematu bazy danych jest przydatne, gdy jest wykonywane jako część kompilacji. W ten sposób możesz sprawdzić plik tekstowy w systemie kontroli kodu źródłowego i mieć historię wersji, w której ewoluował twój schemat. SchemaCrawler jest również zaprojektowany do automatyzacji tego z poziomu wiersza poleceń.


20

Jeśli jest kiedykolwiek napisane, dokumentacja składa się z dokumentu słownego. Dołączonych zostanie kilka diagramów relacji. Listy tabel i krótki opis tego, co zawiera każda tabela i jak odnosi się do innych tabel. Jeden rozdział dokumentacji obejmuje ustawienia zabezpieczeń: jakich uprawnień potrzebuje „użytkownik” aplikacji?

Zasadniczo w firmach, w których pracowałem, dokumentacja bazy danych jest zapisywana tylko wtedy, gdy klient jest tym, który przeprowadza kontrole, co ogranicza jej wykorzystanie do klientów finansowych i rządowych.

Oświadczenie: zdecydowanie zbyt wielu programistów uważa, że kod jest dokumentacją , i ja też byłem winny.


10
Dużym problemem, jaki znajduję w przypadku dokumentacji, która nie jest ściśle związana z kodem (np. Osobny dokument programu Word, w przeciwieństwie do automatycznie generowanego schematu schematu + dobrze nazwanych obiektów bazy danych) jest to, że dokumentacja ta jest całkowicie błędna, ponieważ czas mija. Powód jest prosty: osobny dokument skutecznie powiela informacje. Bez zautomatyzowanego sposobu synchronizacji ze źródłem, bardzo szybko stanie się przestarzały. Porównaj to z narzędziem, które generuje schemat schematu na żywo z bazy danych i wyciąga odpowiednie komentarze z kodu.
Nick Chammas,

16

Używam rozszerzonych właściwości i Red Gates SQL Doc. Działa bardzo dobrze!


14

Zabawne, zastanawiałem się, jak robią to inni.

Podczas opracowywania mojego pierwszego dużego projektu bazy danych odkryłem, że Microsoft SQL Server Management Studio 10.0.1600.22 obsługuje diagramy baz danych, które możesz wyeksportować do dokumentu programu Word lub innego oprogramowania dokumentacyjnego, w którym możesz dodać tyle szczegółów dokumentacji, ile chcesz. Po prostu rozwiń bazę danych, z którą się połączyłeś w SQL Management Studio i kliknij prawym przyciskiem myszy „diagramy bazy danych” w eksploratorze obiektów i wybierz „Nowy diagram bazy danych”, aby wygenerować interaktywny diagram, który pokaże wszystkie relacje między różnymi tabelami. Możesz nawet określić, które tabele chcesz uwzględnić na schematach, aby obraz nie uległ pogorszeniu, jeśli tylko próbujesz dokumentować go kawałek po kawałku. Eksportuj obraz do dowolnego innego oprogramowania do edycji i komentuj tyle, ile chcesz.

Polecam również dużo / comments / w skrypcie, który generuje bazę danych.

Zasadniczo spisywanie tego, po co to wszystko, jest dużo pracy, ale dobry pomysł na dłuższą metę, na przykład kiedy ty lub inna biedna dusza wrócisz, aby zaktualizować swoje dzieło kilka lat później! :)


3
Nie używam diagramów SQL Server, ponieważ ograniczenia klucza obcego są po prostu połączone gdzieś z tabelami, tak jak dzieje się to w diagramach ER . Wolę mieć złącza łączące pola klucza głównego i klucza obcego.
R. Schreurs,

13

Ustawiam rozszerzoną właściwość MS_description dla wszystkich obiektów, a następnie dokumentuję całą bazę danych za pomocą ApexSQL Doc . Wcześniej tworzyłem dokumenty HTML, ale ostatnio wolę PDF


12

Używam narzędzi do modelowania danych, ponieważ pozwalają mi dokumentować ważne informacje o bazie danych inne niż to, co „pasuje” do bazy danych. Metadane, takie jak obawy dotyczące prywatności / bezpieczeństwa / wrażliwości, zarządzanie, zarządzanie itp.

To może wykraczać poza to, czego niektórzy potrzebują do udokumentowania bazy danych, ale te rzeczy są ważne dla firmy i pomagają jej zarządzać danymi.

Narzędzia formalne pomagają mi również w zarządzaniu danymi przechowywanymi w więcej niż jednej bazie danych / instancji / serwerze. To nigdy nie było tak prawdziwe jak w naszym świecie aplikacji pakietowych.


10

W przypadku serwera SQL Documenting bardzo polecam niedawno wydane:

Dokumentacja SQL Server i Windows za pomocą Windows PowerShell napisana przez Kendal Van Dyke

Krótki opis z linku:

SQL Power Doc to zbiór skryptów i modułów Windows PowerShell, które wykrywają, dokumentują i diagnozują wystąpienia SQL Server oraz ich leżące u ich podstaw konfiguracje systemu operacyjnego Windows i komputera. SQL Power Doc współpracuje ze wszystkimi wersjami SQL Server od SQL Server 2000 do 2012 oraz wszystkimi wersjami Windows Server i konsumenckich systemów operacyjnych Windows od Windows 2000 i Windows XP do Windows Server 2012 i Windows 8. SQL Power Doc jest również w stanie dokumentować Bazy danych SQL systemu Windows Azure.


10

DB Dictionary Creator

to narzędzie do dokumentacji baz danych typu open source z przyzwoitym GUI i opcjami eksportu / importu. Używa rozszerzonych właściwości do przechowywania dokumentacji. Generuje także automatyczne opisy dla kolumn klucza podstawowego i kolumny klucza obcego.


1
wymaga .NET Framework 4.0 i działa tylko z SQL Server i SQL Express
kevinsky

8

Rzeczywiście, Rozszerzone właściwości (MS_Description) to droga. Udostępnienie tych opisów jako części metadanych może być wykorzystane nie tylko przez generatory dokumentów, ale także (mam nadzieję, że pewnego dnia) narzędzia zapewniające „inteligencję”, na przykład doskonały asystent SQL Softtree http://www.softtreetech.com/ isql.htm (ostatni raz sprawdziłem, że nie mają) lub wbudowany w Intellisense SQL Sever Management Studio (od sql2008)

Uważam również, że deweloperzy i DBA powinni łatwo dodawać te notatki, ponieważ jak słusznie zauważyli Tangurena i Nick Chammas - deweloperzy bardzo niechętnie aktualizują dokumentację i nienawidzą powielania pracy - co jest wystarczające, szczególnie dla osoby, która była nauczana optymalizować rzeczy przez całe życie zawodowe. Więc chyba, że ​​aktualizacja dokumentów w jednym miejscu blisko kodu źródłowego jest naprawdę łatwa - to nie zadziała. W pewnym momencie przeszukałem sieć i nie znalazłem rozwiązania tego problemu, więc napisałem LiveDoco (nie za darmo, przepraszam), aby to ułatwić. Więcej informacji tutaj, jeśli są zainteresowani: http://www.livedoco.com/why-livedoco


7

Możesz także rzucić okiem na wsSqlSrvDoc . To ładne małe narzędzie, które współpracuje z rozszerzonymi właściwościami SQL Server i tworzy dokument MS Word.

Wydruk wszystkich właściwości kolumny (z relacjami klucza obcego) działa natychmiast po wyjęciu z pudełka. Aby uzyskać dalsze opisy dla każdego pola, musisz skonfigurować rozszerzone właściwości tych kolumn w SQL Server Management Studio.

To nie jest darmowe, ale dość przystępne. Jeśli potrzebujesz tylko utworzyć dokumentację bazy danych „nie działa w toku”, która jest mniej lub bardziej ukończona, wystarczyłoby skorzystać z bezpłatnej wersji próbnej.

Witryna z narzędziami


5

Używamy Dataedo do tworzenia słownika danych, dokumentowania przechowywanych procedur i funkcji. Wklejamy ERD utworzone w Visio. Cała dokumentacja jest przechowywana w repozytorium metadanych Dataedo (sformatowany tekst), a my eksportujemy ją do HTML do użytku wewnętrznego lub eksportujemy do PDF w celu wydrukowania dokumentu.

Przypisujemy każdy obiekt do modułu i przypisujemy każdy moduł do osoby. Dataedo zawiera raportowanie stanu dokumentacji, dzięki czemu możemy stwierdzić, czy istnieje nowa kolumna lub tabela, którą należy udokumentować.


1

W pliku można używać --komentarzy z regularnymi prefiksami .sql.

Korzyści obejmują to, że dokumentacja zawiera kod schematu bazy danych i można łatwo zatwierdzić go w systemie kontroli wersji, takim jak Git .

Przykład:

-- Table to store details about people.
-- See also: The customer table.
-- Note: Keep this data safe!
-- Todo: Add a email column.
CREATE TABLE Persons ( -- People in the registry
    PersonID int,
    LastName varchar(255), -- The person's last name
    FirstName varchar(255), -- The person's first name
    Address varchar(255), -- Address of residence
    City varchar(255) -- City of residence
);

Może mógłbyś również użyć XML.

-- <summary>
-- Table to store details about people.
-- </summary>
-- <column name="PersonID">The id column.</column>
-- <column name="LastName">The person's last name.</column>
-- <column name="FirstName">The person's first name.</column>
-- <column name="Address">Address of residence.</column>
-- <column name="City">City of residence.</column>
CREATE TABLE Persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
);

Można również korzystać z niektórych składni z podobieństwem JSDoc / PHPDoc .

-- Table to store details about people.
-- @column {int} PersonID - The id column.
-- @column {varchar} LastName - The person's last name.
-- @column {varchar} FirstName - The person's first name.
-- @column {varchar} Address - Address of residence.
-- @column {varchar} City - City of residence.
-- @see {@link https://example.com/|Example}
-- @author Jane Smith <jsmith@example.com>
-- @copyright Acme 2018
-- @license BSD-2-Clause
-- @todo Add a column for email address.
-- @since 1.0.1
-- @version 1.2.3
CREATE TABLE Persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
);

Lub możesz użyć składni MarkDown.

-- # Persons
-- Table to store details about **people**.
-- * `PersonID` - The id column.
-- * `LastName` - The person's _last_ name.
-- * `FirstName` - The person's _first_ name.
-- * `Address` - Address of residence.
-- * `City` - City of residence.
--
-- [I'm an inline-style link](https://www.example.com/)
--
-- | PersonID | LastName | FirstName | Address | City |
-- | ---------| -------- | --------- | ------- | ---- |
-- | 1        | Smith    | Jane      | N/A     | N/A  |
CREATE TABLE Persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
);

1

Diagramy ERD (diagramy bazy danych) zawsze były najbardziej przydatne dla mojego zespołu

Ale istnieje zasada, aby napisać „ Decription ” we właściwościach każdej tabeli i kolumny, którą tworzymy.

Następnie używamy nazwę oprogramowania Enterprise Architect dokumentować Tablesze wszystkim Indexes, Foreign KeysI Columnsze Typei opis .

wprowadź opis zdjęcia tutaj


-1

W szczególności w przypadku MySQL zawsze używamy MySQL Workbench . Tworzymy projekty baz danych w projektancie, a następnie eksportujemy je jako działający skrypt SQL. Zastosowanie wszystkich zmian w projekcie, a następnie uruchomienie wygenerowanego skryptu gwarantuje, że projekt i rzeczywista baza danych są idealnie zsynchronizowane ze sobą, a dokumentacja nie stanie się tak łatwo przestarzała.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.