Как вы документируете свои базы данных?


227

Я считаю, что большинство моих клиентов вообще не документируют свои базы данных, и я нахожу это довольно пугающим. Чтобы познакомить вас с лучшей практикой, я хотел бы знать, какие инструменты / процессы используют люди.

  • Как вы документируете свою базу данных? (SQL-сервер)
  • Какой инструмент вы используете?
  • Формат хранения документации для схемы базы данных / метаданных?
    • Word документы
    • Таблица Excel
    • Простой текст
  • Процесс документации или политики?

Я не говорю о реверс-инжиниринге / документировании существующей базы данных, но в основном о лучших методах документирования при разработке вашей системы / базы данных.

Ответы:


78

Я использую расширенные свойства, так как они очень гибкие. Большинство стандартных инструментов документирования можно отключить MS_Description, а затем вы можете использовать свои собственные с помощью пользовательских инструментов.

Смотрите эту презентацию: # 41-Возьми рычаг и выбери любую черепаху: снятие метаданных

И этот код: http://code.google.com/p/caderoux/wiki/LeversAndTurtles


3
Вы можете что-то изменить и забыть изменить свои расширенные свойства соответственно, делая их неправильными. Можете ли вы автоматически обнаружить такие расхождения?
AK

2
По крайней мере, можно запросить схему базы данных (sys.tables / sys.columns) и оставить соединение с ее расширенными свойствами (sys.extended_properties), чтобы определить недокументированные поля, а затем превратить этот скрипт в тест для запуска при развертывании.
Мика

59

От Microsoft Visio Pro (до Visio 2010) может перепроектировать базу данных , как может СА ERwin . Visio - более дешевый вариант, но ERwin - более подробный и более полный. Расширенные свойства хороши, если люди потрудились посмотреть на них. Вы также можете использовать что-то вроде SQL-документа Red Gate для вывода документации в формате HTML.

Я считаю, что соглашения об именах и правильная настройка внешних ключей приводят к почти самодокументируемой базе данных. У вас все еще должны быть внешние документы для лучшего понимания цели.


Чего не хватает в простой схеме (даже в базе данных с хорошими именами и внешними ключами), так это в описании полей. По моему опыту, все поля достаточно просты, чтобы соответствовать имени столбца.
StockB


26

Для SQL Server я использую расширенные свойства.

С помощью следующего скрипта PowerShell я могу сгенерировать скрипты Create Table для одной таблицы или для всех таблиц в схеме dbo.

Скрипт содержит Create tableкоманду, первичные ключи и индексы. Внешние ключи добавляются как комментарии. Расширенные свойства таблиц и столбцов таблицы добавляются в качестве комментариев. Да, многострочные свойства поддерживаются.

Сценарий настроен на мой личный стиль кодирования.

  • нет отдельных сопоставлений для отдельных столбцов.

  • в настоящее время требуется проверка подлинности сервера Sql.

Вот полный код для превращения расширенных свойств в старый добрый старый документ ASCII (кстати, это действительно sql для воссоздания ваших таблиц):

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

Вы можете написать сценарий полной схемы dbo для данной базы данных.

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

Или фильтр для одной таблицы

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

21

Взгляните на SchemaCrawler - это мой бесплатный инструмент командной строки, который я разработал, чтобы делать то, что вы ищете. SchemaCrawler создает текстовый файл со всеми объектами схемы базы данных. Этот текстовый вывод предназначен как для чтения человеком, так и для сравнения с аналогичным выводом с другого сервера.

На практике я обнаружил, что вывод текстового файла схемы базы данных полезен, когда выполняется как часть сборки. Таким образом, вы можете проверить текстовый файл в вашей системе управления исходным кодом и иметь историю версий того, как ваша схема развивалась с течением времени. SchemaCrawler также предназначен для автоматизации этого из командной строки.


20

Если это когда-либо написано, документация состоит из текстового документа. Пара диаграмм отношений будут включены. Списки таблиц и краткое описание того, что содержит каждая таблица и как она связана с другими таблицами. Одна глава документации включает параметры безопасности: какие разрешения нужны «пользователю» для приложения?

Как правило, в компаниях, в которых я работал, документация по базе данных записывается только тогда, когда заказчиком является тот, кто проводит аудит, что ограничивает его использование финансовыми и государственными клиентами.

Отказ от ответственности: слишком многие разработчики придерживаются мнения, что код является документацией , и я тоже был виновен в этом.


10
Большая проблема, которую я нахожу с документацией, которая не связана тесно с кодом (например, отдельным документом Word, в отличие от автоматически генерируемой схемы схемы + хорошо именованные объекты базы данных), состоит в том, что эта документация гарантированно будет отображаться неправильно, так как Время проходит. Причина проста: отдельный документ эффективно дублирует информацию. Без автоматического способа синхронизировать его с источником он очень быстро устареет. Сравните это с инструментом, который генерирует диаграмму схемы в реальном времени из базы данных и извлекает соответствующие комментарии из кода.
Ник Чаммас

16

Я использую расширенные свойства и Red Gates SQL Doc. Работает очень хорошо!


14

Забавно, мне было интересно, как это делают другие люди ..

Разрабатывая мой первый большой проект базы данных, я обнаружил, что Microsoft SQL Server Management Studio 10.0.1600.22 поддерживает диаграммы базы данных, которые вы можете экспортировать в текстовый документ или другое программное обеспечение для документирования, куда вы можете добавить столько деталей документации, сколько захотите. Просто разверните базу данных, к которой вы подключились, в SQL Management Studio, щелкните правой кнопкой мыши на «диаграммах базы данных» в проводнике объектов и выберите «Новая диаграмма базы данных», чтобы создать интерактивную диаграмму, которая покажет все взаимосвязи между различными таблицами. Вы даже можете указать, какие таблицы вы хотите включить в диаграммы, чтобы изображение не выглядело непривлекательно, если вы просто пытаетесь задокументировать его по частям. Экспортируйте изображение в любое другое программное обеспечение для редактирования и комментируйте столько, сколько хотите.

Я также рекомендую множество / comments / в скрипте, который генерирует вашу базу данных.

Как правило, это большая работа, чтобы записать, для чего все это, но хорошая идея на долгое время, например, когда вы или какая-то другая бедная душа возвращаетесь, чтобы обновить свое творение пару лет спустя! :)


3
Я не использую диаграммы SQL Server, поскольку ограничения внешнего ключа просто где-то связаны с таблицами, как это делается в ER-диаграммах . Я предпочитаю иметь соединители, соединяющие поля первичного и внешнего ключей.
Р. Шреурс

13

Я установил расширенное свойство MS_description для всех объектов, а затем задокументировал всю базу данных, используя ApexSQL Doc . Я раньше создавал документы HTML, но в последнее время предпочитаю PDF


12

Я использую инструменты моделирования данных, потому что они позволяют мне документировать важную информацию о базе данных, кроме того, что «вписывается» в базу данных. Метаданные, такие как вопросы конфиденциальности / безопасности / чувствительности, руководство, управление и т. Д.

Это может выходить за рамки того, что нужно некоторым при документировании базы данных, но эти вещи важны для бизнеса и помогают им управлять своими данными.

Формальные инструменты также помогают мне управлять данными, которые хранятся в нескольких базах данных / экземплярах / серверах. Это никогда не было так верно, как в нашем мире упакованных приложений.


10

Для Документирования сервера sql я настоятельно рекомендую только что вышедшую:

Документация по SQL Server и Windows с использованием Windows PowerShell, написанная Кендалом Ван Дайком

Краткое описание по ссылке:

SQL Power Doc представляет собой набор сценариев и модулей Windows PowerShell, которые обнаруживают, документируют и диагностируют экземпляры SQL Server и их базовые конфигурации ОС и компьютеров Windows. SQL Power Doc работает со всеми версиями SQL Server от SQL Server 2000 до 2012 года, а также со всеми версиями Windows Server и потребительских операционных систем Windows от Windows 2000 и Windows XP до Windows Server 2012 и Windows 8. SQL Power Doc также способен документировать Windows Azure SQL Базы данных.


10

Создатель словаря БД

является инструментом документации базы данных с открытым исходным кодом с приличным графическим интерфейсом и опциями экспорта / импорта. Он использует расширенные свойства для хранения документации. Он также генерирует автоматические описания для столбцов первичного ключа и столбцов внешнего ключа.


1
требует .NET Framework 4.0 и работает только с SQL Server и SQL Express
kevinsky

8

Действительно, Расширенные свойства (MS_Description) - это путь. Наличие этих описаний, легко доступных как часть метаданных, может быть использовано не только генераторами документов, но также (надеюсь, однажды) инструментами, которые предоставляют «intellisense», например, превосходный SQL-помощник Softtree http://www.softtreetech.com/ isql.htm (последний раз, когда я проверял, что нет) или встроенный в SQL Sever Management Studio Intellisense (начиная с sql2008)

Я также полагаю, что разработчикам и администраторам баз данных будет легко добавить эти заметки, потому что, как правильно отметили Тангурена и Ник Чаммас, разработчики очень неохотно обновляют документы и ненавидят дублирующую работу, что достаточно справедливо, особенно для человека, которого учили оптимизировать вещи в течение всей своей профессиональной жизни. Поэтому, если действительно не так просто обновить документы в одном месте, близком к исходному коду, это не сработает. В какой-то момент я искал в Интернете и не нашел решения для этого, поэтому я написал LiveDoco (не бесплатно, извините), чтобы упростить его. Более подробная информация здесь, если вы заинтересованы: http://www.livedoco.com/why-livedoco


7

Вы также можете взглянуть на wsSqlSrvDoc . Это хороший маленький инструмент, который работает с расширенными свойствами SQL Server и создает документ MS Word.

Распечатка всех свойств столбца (с отношениями внешнего ключа) работает "из коробки". Для дальнейшего описания каждого поля необходимо настроить расширенные свойства этих столбцов в SQL Server Management Studio.

Это не бесплатно, но вполне доступно. Если вам просто нужно создать документацию для БД «не в процессе», которая более или менее закончена, чем было бы достаточно для использования бесплатной пробной версии.

Веб-сайт инструмента


5

Мы используем Dataedo для создания словаря данных, документирования хранимых процедур и функций. Мы вставляем ERD, созданные в Visio. Вся документация хранится в хранилище метаданных Dataedo (форматированный текст), и мы экспортируем ее в HTML для внутреннего использования или экспортируем в PDF для печатного документа.

Мы присваиваем каждый объект модулю и назначаем каждый модуль человеку. Dataedo поставляется с отчетностью о состоянии документации, поэтому мы можем определить, есть ли новый столбец или таблица, которые необходимо документировать.


1

Вы можете использовать обычные --комментарии с префиксом в .sqlфайле.

Преимущества заключаются в том, что документация содержит код для схемы базы данных, и вы можете легко зафиксировать ее в системе управления версиями, такой как Git .

Пример:

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

Может быть, вы тоже можете использовать 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)
);

Вы также можете использовать синтаксис, похожий на 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)
);

Или вы можете использовать синтаксис 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

Диаграммы ERD (диаграммы баз данных) всегда были самыми полезными для моей команды

Но есть правило писать « Описание » в свойствах каждой таблицы и столбца, которые мы создаем.

Затем мы используем имя программного обеспечения Enterprise Architect к документу Tablesсо всеми Indexes, Foreign Keysи Columnsс Typeи описанием .

введите описание изображения здесь


-1

В частности, для MySQL мы всегда используем MySQL Workbench . Мы создаем наши дизайны базы данных в конструкторе, а затем экспортируем их в виде исполняемого сценария SQL. Применение всех изменений в дизайне и последующий запуск сгенерированного скрипта гарантирует, что дизайн и фактическая база данных будут идеально синхронизированы друг с другом, и что документация не так уж быстро устареет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.