Come documentate i vostri database?


227

Trovo che la maggior parte dei miei clienti non stia documentando affatto i loro database e lo trovo piuttosto spaventoso. Per introdurre alcune pratiche migliori, vorrei sapere quali strumenti / processi utilizzano le persone.

  • Come documentate il vostro database? (Server SQL)
  • Quale strumento usi?
  • Formato di archiviazione della documentazione per schema / metadati del database?
    • Documenti Word
    • Foglio di calcolo Excel
    • Testo semplice
  • Processo o politiche di documentazione?

Non sto parlando di reverse engineering / documentare un database esistente, ma principalmente sulle migliori pratiche di documentazione mentre sviluppi il tuo sistema / database.

Risposte:


78

Ho usato proprietà estese poiché sono molto flessibili. La maggior parte degli strumenti di documentazione standard può essere disattivata MS_Descriptione quindi è possibile utilizzare i propri con strumenti personalizzati.

Vedi questa presentazione: # 41-Prendi una leva e scegli una tartaruga: sollevare con metadati

E questo codice: http://code.google.com/p/caderoux/wiki/LeversAndTurtles


3
Puoi modificare qualcosa e dimenticare di modificare le proprietà estese di conseguenza, rendendole errate. Riesci a rilevare automaticamente tali discrepanze?
AK,

2
Per lo meno, si potrebbe interrogare lo schema del database (sys.tables / sys.columns) e lasciarlo unito alle sue proprietà estese (sys.extended_properties) per identificare i campi non documentati, quindi trasformare quello script in un test da eseguire durante la distribuzione.
Michea il

59

Microsoft Visio Pro (fino a Visio 2010) può decodificare un database come CA ERwin . Visio è l'opzione più economica, ma ERwin è l'opzione più dettagliata e più completa. Le proprietà estese sono belle se le persone si disturbano a guardarle. Puoi anche usare qualcosa come il documento SQL di Red Gate per produrre documentazione in formato HTML.

Trovo che le convenzioni di denominazione e l'impostazione corretta delle chiavi esterne conducano a un database quasi autocompattante. Dovresti comunque avere alcuni documenti esterni per una migliore comprensione dello scopo.


Ciò che manca spesso a uno schema semplice (anche in un database ben definito e con chiave esterna) sono le descrizioni dei campi. È insolito nella mia esperienza avere tutti i campi abbastanza semplici da adattarsi al nome della colonna.
StockB,


26

Per SQL Server sto usando proprietà estese.

Con il seguente script PowerShell posso generare uno script Crea tabella per singola tabella o per tutte le tabelle nello schema dbo.

Lo script contiene un Create tablecomando, chiavi primarie e indici. Le chiavi esterne vengono aggiunte come commenti. Le proprietà estese delle tabelle e delle colonne della tabella vengono aggiunte come commenti. Sì, sono supportate le proprietà multi linea.

La sceneggiatura è sintonizzata sul mio stile di codifica personale.

  • nessuna raccolta individuale per colonne singole.

  • attualmente richiede l'autenticazione SQL Server.

Ecco il codice completo per trasformare le proprietà estese in un buon vecchio documento ASCII semplice (A proposito, è sql valido per ricreare le tue tabelle):

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

È possibile eseguire lo script dello schema dbo completo di un determinato database

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

O filtro per una singola tabella

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

21

Dai un'occhiata a SchemaCrawler : è il mio strumento da riga di comando gratuito che ho progettato per fare quello che stai cercando. SchemaCrawler produce un file di testo con tutti gli oggetti schema del database. Questo output di testo è progettato per essere sia leggibile dall'uomo, sia diffondibile con output simile da un altro server.

In pratica, quello che ho scoperto è che l'output di un file di testo dello schema del database è utile, se fatto come parte della build. In questo modo, puoi controllare il file di testo nel tuo sistema di controllo del codice sorgente e avere una cronologia delle versioni di come il tuo schema si è evoluto nel tempo. SchemaCrawler è progettato per automatizzare anche questo, dalla riga di comando.


20

Se mai scritto, la documentazione è costituita da un documento word. Verranno inclusi un paio di diagrammi di relazione. Elenco delle tabelle e una breve descrizione di ciò che ogni tabella contiene e di come si collega ad altre tabelle. Un capitolo della documentazione include le impostazioni di sicurezza: quali autorizzazioni è "l'utente" di cui l'applicazione ha bisogno?

Generalmente, nelle aziende per cui ho lavorato, la documentazione del database viene scritta solo quando il cliente è colui che esegue gli audit, il che tende a limitarne l'uso ai clienti finanziari e governativi.

Disclaimer: troppi sviluppatori hanno l'atteggiamento che il codice sia la documentazione , e anche io ne sono stato colpevole.


10
Un grosso problema che riscontro con la documentazione che non è strettamente legata al codice (ad es. Un documento Word separato, al contrario di uno schema di schema generato automaticamente + oggetti di database ben definiti) è che questa documentazione è garantita come completamente sbagliata come il tempo passa. Il motivo è semplice: un documento separato duplica effettivamente le informazioni. Senza un modo automatizzato per mantenerlo sincronizzato con la fonte, diventerà obsoleto molto rapidamente. Confrontalo con uno strumento che genera uno schema dal vivo dal database e estrae i commenti appropriati dall'interno del codice.
Nick Chammas,

16

Uso le proprietà estese e Red Gates SQL Doc. Funziona molto bene!


14

Divertente, mi chiedevo come lo stiano facendo anche altre persone ...

Durante lo sviluppo del mio primo grande progetto di database, ho scoperto che Microsoft SQL Server Management Studio 10.0.1600.22 supporta diagrammi di database che è possibile esportare in un documento word o altro software di documentazione in cui è possibile aggiungere tutti i dettagli della documentazione che si desidera. Espandi semplicemente il database a cui ti sei connesso su SQL Management Studio e fai clic con il tasto destro su "diagrammi di database" in Esplora oggetti e seleziona "Nuovo diagramma di database" per generare un diagramma interattivo che mostrerà tutte le relazioni tra le diverse tabelle. Puoi anche specificare quali tabelle vuoi includere nei diagrammi, in modo che l'immagine non diventi sgraziata se stai solo cercando di documentarla pezzo per pezzo. Esporta l'immagine su qualsiasi altro software di modifica e commenta quanto vuoi.

Raccomando anche un sacco di / commenti / nello script che genera il tuo database.

Generalmente è un sacco di lavoro scrivere ciò per cui è tutto, ma una buona idea a lungo termine, come quando tu o qualche altra povera anima ritorni ad aggiornare la tua creazione un paio di anni dopo! :)


3
Non uso i diagrammi di SQL Server, poiché i vincoli di chiave esterna sono semplicemente collegati da qualche parte alle tabelle, come avviene nei diagrammi ER . Preferisco avere i connettori che collegano i campi chiave primaria ed esterna.
R. Schreurs,

13

Ho impostato la proprietà estesa MS_description per tutti gli oggetti e quindi ho documentato l'intero database usando ApexSQL Doc . Prima creavo documenti HTML, ma ultimamente preferisco PDF


12

Uso strumenti di modellazione dei dati perché mi consentono di documentare informazioni importanti sul database diverse da quelle che "rientrano" in un database. Meta-dati come problemi di privacy / sicurezza / sensibilità, gestione, governance, ecc.

Ciò potrebbe andare oltre ciò di cui alcuni hanno bisogno nel documentare un database, ma queste cose sono importanti per l'azienda e per aiutarle a gestire i propri dati.

Gli strumenti formali mi aiutano anche nella gestione dei dati archiviati in più database / istanze / server. Questo non è mai stato più vero che nel nostro mondo di applicazioni in pacchetto.


10

Per Documenting sql server, consiglio vivamente rilasciato di recente:

Documentazione su SQL Server e Windows Utilizzo di Windows PowerShell scritto da Kendal Van Dyke

Breve descrizione dal link:

SQL Power Doc è una raccolta di script e moduli di Windows PowerShell che rilevano, documentano e diagnosticano le istanze di SQL Server e le relative configurazioni del sistema operativo e del computer Windows. SQL Power Doc funziona con tutte le versioni di SQL Server da SQL Server 2000 a 2012 e tutte le versioni di Windows Server e sistemi operativi Windows consumer da Windows 2000 e Windows XP a Windows Server 2012 e Windows 8. SQL Power Doc è anche in grado di documentare Database SQL di Windows Azure.


10

DB Dictionary Creator

è uno strumento di documentazione del database open source con una buona interfaccia grafica e opzioni di esportazione / importazione. Utilizza le proprietà estese per archiviare la documentazione. Genera anche descrizioni automatiche per colonne chiave primaria e colonne chiave esterna.


1
richiede .NET Framework 4.0 e funziona solo con SQL Server e SQL Express
kevinsky il

8

Infatti, Extended Properties (MS_Description) è la strada da percorrere. Avere queste descrizioni prontamente disponibili come parte dei metadati potrebbe essere utilizzato non solo dai generatori di documenti ma anche (si spera un giorno) da strumenti che forniscano "intellisense", ad esempio l'eccellente SQL Assistant di Softtree http://www.softtreetech.com/ isql.htm (l'ultima volta che ho controllato che non lo facessero) o integrato in Intellisense di SQL Sever Management Studio (dal sql2008)

Credo anche che dovrebbe essere facile per gli sviluppatori e gli amministratori di database aggiungere queste note perché, come hanno correttamente sottolineato Tangurena e Nick Chammas, gli sviluppatori sono molto riluttanti a mantenere aggiornati i documenti e odiano il lavoro duplicato, il che è abbastanza giusto soprattutto per una persona a cui è stato insegnato per ottimizzare le cose durante la loro intera vita professionale. Quindi, a meno che non sia davvero facile aggiornare i documenti in un posto vicino al codice sorgente, questo non funzionerà. Ad un certo punto ho cercato sul web e non ho trovato una soluzione, quindi ho scritto LiveDoco (non gratuito, mi dispiace) nel tentativo di semplificarlo. Maggiori informazioni qui se interessati: http://www.livedoco.com/why-livedoco


7

Puoi anche dare un'occhiata a wsSqlSrvDoc . È un piccolo strumento che funziona con le proprietà estese di SQL Server e crea un documento MS Word.

La stampa di tutte le proprietà della colonna (con relazioni di chiave esterna) funziona immediatamente. Per ulteriori descrizioni su ciascun campo è necessario impostare le proprietà estese di tali colonne in SQL Server Management Studio.

Non è gratuito ma abbastanza conveniente. Se hai solo bisogno di creare una documentazione per un DB "non in corso" che è più o meno finito di quanto sarebbe sufficiente per utilizzare la prova gratuita.

Sito Web dello strumento


5

Usiamo Dataedo per creare un dizionario di dati, documentare procedure e funzioni memorizzate. Incolliamo ERD creati in Visio. Tutta la documentazione è archiviata nel repository di metadati di Dataedo (testo formattato) e la esportiamo in HTML per uso interno o esportiamo in PDF per documenti stampati.

Assegniamo ogni oggetto a un modulo e assegniamo ogni modulo a una persona. Dataedo viene fornito con i rapporti sullo stato della documentazione in modo da poter dire se c'è una nuova colonna o tabella che deve essere documentata.


1

È possibile utilizzare i normali --commenti prefissati nel .sqlfile.

I vantaggi includono che la documentazione è con il codice per lo schema del database e puoi facilmente impegnarlo in un sistema di controllo della versione come Git .

Esempio:

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

Forse potresti usare anche 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)
);

È inoltre possibile utilizzare una sintassi simile alla 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)
);

Oppure potresti usare la sintassi di 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

I diagrammi ERD (diagrammi di database) sono sempre stati i più utili per il mio team

Ma c'è una regola per scrivere " Decription " in Proprietà di ogni tabella e colonna che creiamo.

Quindi usiamo un nome software come Enterprise Architect per documentare Tablescon tutto Indexes, Foreign Keyse Columnscon Typee descrizione .

inserisci qui la descrizione dell'immagine


-1

Per MySQL in particolare, utilizziamo sempre MySQL Workbench . Creiamo i nostri progetti di database nel designer, quindi esportiamo come script SQL eseguibile. Applicando tutte le modifiche nella progettazione e quindi eseguendo lo script generato si assicura che la progettazione e il database reale siano perfettamente sincronizzati tra loro e che la documentazione non diventerà obsoleta così facilmente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.