После того как вы создали базу данных (с файлами и группами файлов), следующим шагом должно стать создание таблиц. Таблицы являются объектами, при помощи которых вы организовываете и храните свои данные. В этой лекции мы расскажем о главных решениях, принимаемых при создании таблиц базы данных. Так как возможны многие варианты настроек, то создание таблиц базы данных может оказаться несколько сложным процессом. Сначала мы рассмотрим основные требования к таблицам, а затем изучим некоторые настройки, сопровождая наше изложение примерами.
В данной лекции вы познакомитесь с системными и null -значения и свойство IDENTITY. Вы также научитесь создавать таблицы при помощи Enterprise Manager и команд Transact SQL (T-SQL). Мы также вкратце затронем здесь другие важные вопросы, относящиеся к созданию таблиц, такие как ограничения, значения по умолчанию и индексы, о которых будет рассказано более подробно в последующих лекциях.
Когда вы приступите к проектированию своих таблиц базы данных, вам потребуется принять некоторые решения, относящиеся к их структуре. К этим решениям относится определение того, какие элементы данных должны храниться в этих таблицах и как таблицы будут связаны друг с другом. Эта работа поможет представить общую картину базы данных, прежде чем вы углубитесь в создание таблиц. Ниже дан перечень этих глобальных решений:
Постарайтесь найти ответы на как можно большее количество этих вопросов о проектировании системы и записать их на листок бумаги или в компьютерной программе для рисования схем, чтобы осознать общую конструкцию таблиц вашей базы данных, прежде чем начать создавать их. Нужно также узнать у ваших пользователей, каким образом будут осуществляться доступ к данным. Например, можно узнать, что некоторая таблица будет предназначена только для чтения или же будут производиться вставки, удаления или обновления данных. Узнайте, какие запросы будут выполняться чаще всего и из каких колонок будут извлекаться данные. Определите, какая информация действительно необходима для базы данных, а какую хранить не надо. Ответы на эти вопросы помогут вам принять решения о том, как создавать таблицы и индексы, какие ограничения могут применяться, какие значения по умолчанию могут оказаться полезными и т.д. А теперь давайте научимся создавать таблицы на основе этого "фундамента".
В данном разделе вы познакомитесь с некоторыми простыми, но важными понятиями, относящимися к таблицам. Мы рассмотрим пример базы данных, в котором вы познакомитесь с основными элементами таблиц и узнаете о системных типах данных и о том, как создавать и удалять
Таблица – это объект базы данных, который хранит данные в виде совокупности строк и колонок. Таблица определяется содержащимися в ней колонками. Данные организованы в форме, похожей на электронные таблицы Excel (см. пример таблицы Product_Info, показанный в табл. 10.1). Таблица Product_Info, используемая в наших примерах, будет создана в базе данных MyDB.
Таблица Product_Info применяется для хранения информации обо всех продуктах, продаваемых в магазине. Когда продукт становится готов к продаже, данные о нем добавляются в новую строку таблицы Product_Info. Эта таблица состоит из пяти колонок: Product_ID (Идентификатор продукта), Product_Name (Название продукта), Description (Описание), Price (Цена) и Brand_ID (Название торговой марки). В табл. 10.1 показаны в качестве примера три строки данных из таблицы Product_Info. Оператор T-SQL, применявшийся для создания этой таблицы (пустой, без данных) показан в разделе "Создание таблицы Product_Info с использованием системных типов данных" далее в этой лекции. (Об использовании оператора INSERT, применяемого для вставки данных в таблицы см. лекцию 20.)
| Product_ID | Product_Name | Description | Price | Brand_ID |
|---|---|---|---|---|
| 1 | Пятифутовый тент | Для одного-двух человек | 80.00 | 12 |
| 2 | Мини-печь | Работает на керосине | 20.00 | 33 |
| 3 | Рюкзак | Со стальным каркасом | 60.00 | 15 |
Мы вернемся к этому примеру таблицы базы данных в этой лекции, когда будем объяснять более сложные вопросы создания таблиц. Но сначала мы продолжим рассказ об основах, которые вы должны знать, чтобы уметь создавать таблицы.
Чтобы задать таблицу, вы должны решить, сколько колонок она будет иметь и данные каких типов (например, символьные или числовые) смогут храниться в каждой из колонок. Вы должны также задать допустимый диапазон для этих данных, например, вы можете разрешить использовать не более 30 символов или числа, хранимые в 4 байтах. Эти атрибуты задаются благодаря тому, что каждой колонке присваивается некоторый тип данных, являющийся набором атрибутов, определяющих тип и диапазон данных, способных храниться в этой колонке. Вы можете пользоваться многими системными типами данных, имеющимися в SQL Server, а можете создать и свой собственный тип данных, основанный на системных типах данных. (Вы не можете изменять системные типы данных, но можете создавать совершенно новые типы данных.)
Как мы уже говорили, вы задаете тип данных для каждой колонки таблицы. При задании типа данных у колонки задаются следующие атрибуты:
Типы данных могут также применяться к колонкам для представлений, параметров в хранимых процедурах и в функциях T-SQL, возвращающих одно или несколько значений данных. bigint, sql_variant и table. (Кроме нескольких исключений, явно указанных в табл. 10.2, для всех указанных объектов применяются те же самые типы данных.)
| Тип данных | Описание | Сколько места занимает |
|---|---|---|
tinyint |
Целочисленные данные в диапазоне от 0 до 255. | 1 байт |
unique-identifier |
Хранит 16-байтное двоичное значение, являющееся глобальным уникальным идентификатором (GUID) | 16 байт |
varbinary |
Двоичные данные переменной длины, состоящие из n байтов, где n может принимать значение от 1 до 8000. Применяйте тип varbinary, если предполагаете, что элементы данных, хранимые в колонке, будут сильно отличаться по своим размерам | Фактическая длина введенных данных плюс 4 байта |
varchar[(n)] |
Данные переменной длины не в кодировке Unicode, длиной в n символов, где n может принимать значение от 1 до 8000 | Фактическая длина введенных данных |
При создании таблиц важно правильно выбрать типы данных для каждой из колонок. Наверное, вы хотели бы, чтобы позволялось хранить нужные данные, но не разрешалось хранить недопустимые данные (например, символьное значение в колонке для числовых данных). Эта забота и решается благодаря типам данных. При выборе типа данных вам полезно ответить на два следующих вопроса:
Выбор подходящего типа данных является довольно понятным процессом. Данные, которые будут вводиться в колонку, должны соответствовать типу данных, заданному для этой колонки. Поэтому вам следует выбрать такой тип данных, который лучше всего охватит диапазон значений, которые могли бы храниться в колонке для всего срока эксплуатации вашего приложения, и в то же время стремясь ограничить ненужный расход места на диске. Ненужный расход места на диске – это место на диске, выделенное для элементов данных, хранящихся в колонке, но не используемое. Например, предположим, у вас есть колонка, в которой нужно хранить одно целое число в диапазоне от 1 до 100. Очевидно, что эти значения могут храниться в типе integer, но каждое целое число типа integer занимает 4 байта. Данные с типом tinyint могут хранить значения от 0 до 255 и для них нужен только 1 байт места. В данном случае tinyint будет наилучшим выбором, потому что это экономит место на диске, необходимое для хранения данных из таблиц.
Затем вы должны определить, какой тип данных следует использовать – с фиксированной либо с переменной длиной. Если все значения данных из колонки будут иметь приблизительно одинаковые размеры, то более эффективным станет применение типа данных с фиксированной длиной, так как обработка данных, имеющих типы переменной длины, вызывает повышенную нагрузку. Вообще говоря, типы данных с переменной длиной следует применять, только если вы предполагаете значительные различия в длине данных, хранимых в данной колонке, и когда данные из колонки обновляются редко. К данным с переменной длиной относятся varchar, nvarchar, varbinary, text, ntext и image.Применение типов данных с переменной длиной может привести к значительной экономии места для хранения данных. Например, если вы зададите тип данных с фиксированной длиной, достаточной для хранения значений в колонке с наибольшей возможной длиной, то для всех значений, занимающих меньше места, истратиться столько же места, как и для этого самого объемного значения. Результатом этого станут огромный ненужный расход места на диске, потому что лишь немногие строки будут расходовать все максимально допустимое место для данных. В большинстве строк будет использовано меньше места, а все неиспользуемое место станет потерянным. А если вы зададите, что будет применяться тип данных с переменной длиной, то короткие значения будут расходовать лишь то место, которое им действительно нужно. Но опять-таки, применение типов данных с переменной длиной повышает нагрузку на процессор. Поэтому, если вам не требуется тип данных с переменной длиной, то применяйте тип данных с фиксированной длиной. Если из соображений расходования места для хранения данных нужно применять тип данных с переменной длиной, то, конечно, применяйте его.
Итак, как же выбрать нужные для ваших таблиц типы данных и их длины? Следуйте уже принятым ранее основным решениям и делайте выбор, который наилучшим образом будет соответствовать потребностям вашего приложения. Вообще говоря, определяясь с размерами колонок таблиц, старайтесь не тратить зря место на диске и не забывайте о потребностях в будущем.
Прежде чем продолжить наше изложение, давайте рассмотрим T-SQL-оператор CREATE TABLE, которую можно применить для создания таблицы Product_Info, показанной в этой лекции ранее в табл. 10.1. В этом примере мы применим только системные типы данных и колонки с фиксированной длиной. Когда вы создаете таблицу при помощи оператора T-SQL, она создается в базе данных, которой вы пользуетесь в текущий момент. Если вы хотите создать таблицу в какой-либо конкретной базе данных, то надо применить оператор USE имя_базы_данных, как показано в примере кода (в нашем примере база данных имеет имя MyDB). Ключевое слово GO означает, что все предыдущие операторы должны быть теперь выполнены. (Об использовании T-SQL см. лекцию 13.)
USE MyDB GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID smallint ) GO
Давайте посмотрим, что произойдет при исполнении этого кода. После оператора CREATE TABLE следует спецификация таблицы с именем Product_Info. Между открывающей и закрывающей скобками заданы имена колонок и их типы данных. Длины для двух типов данных заданы равными 20 и 30, потому что большинство названий продуктов уместятся в 20 символов, а большинство описаний продуктов уместятся в 30 символов. Для Product_ID и Brand_ID применяется тип данных , а не tinyint, потому что мы предполагаем, что количество разновидностей как продуктов, так и торговых марок, превысит 255 (максимальное значение для типа tinyint ), хотя и будет меньше, чем 32767 (максимальное значение для типа ). Так как значения больше, чем 32767, нам не понадобятся, то при использовании типа int мы напрасно тратили бы место на диске.
Пользовательские типы данных (типы данных, задаваемые пользователями,
Например, предположим, что у нас имеется еще одна таблица, с именем Brands (торговые марки) в той же базе данных, в которой находится таблица Product_Info. Пусть в таблице Brands имеется колонка Brand_ID, соответствующая колонке Brand_ID таблицы Product_Info. Пусть в таблице Brands хранятся названия торговых марок и другая информация, относящаяся к торговым маркам. Чтобы гарантировать, что колонки Brand_ID в обеих таблицах имеют одинаковый тип данных и не допускают null -значений, вы можете создать , или же tinyint, или было ли позволено применять null -значения. Если создать тип данных с понятными именем, то вам не придется беспокоиться о правильности применяемых атрибутов, и вы получите гарантию согласованности данных для всех таблиц.
Вы можете пожелать создать типы данных для таких данных, как телефонные номера, почтовые индексы, номера социального страхования и для любых других данных, которые вы можете четко определить и которые применяются более чем в одной таблице базы данных. При создании типа данных вы должны задать следующую информацию:
null -значений в данном типе данных, т.е., позволяет ли он хранить null -значения (null values). (См. раздел "Применение null-значений" далее в этой лекции.)Как только вы определитесь с этим, можно будет создать тип данных. Для создания пользовательского типа данных с помощью Enterprise Manager выполните следующие действия.
brand_type (рис. 10.2).null -значения, то установите флажок Allow NULLs. (См. раздел "Применение null-значений" далее в этой лекции.)Если вы создали когда-то
В поле-списке в левой части диалогового окна Dependencies показаны объекты базы данных, которые зависят от вашего пользовательского типа данных, а в поле-списке в правой части диалогового окна показаны объекты, от которых зависит ваш

(рис 10.4) Папка User Defined Data Types (Пользовательские типы данных)(рис 10.3) Диалоговое окно Drop Objects (Удалить объекты)
(рис 10.6) Диалоговое окно Dependencies (Зависимости)(рис 10.5) Сообщение об ошибке, появляющееся при попытке удалить тип данных, находящийся в использованииСистемная хранимая процедура sp_addtype является командой T-SQL, применяемой для создания USE имя_базы_данных.) Ниже дан пример команд T-SQL, создающих brand_type в базе данных model:
USE model GO sp_addtype brand_type, 'smallint', 'NOT NULL' GO
Три параметра у sp_addtype – это имя пользовательского типа данных, системный тип данных, на котором основывается новый тип данных и возможность использования null -значений в новом типе данных. Новый тип данных, brand_type, появится во всех вновь создаваемых пользовательских базах данных. Если вы создадите Refresh в меню Action Enterprise Manager’а.
Чтобы удалить ненужный sp_droptype в базе данных, в которой этот тип данных был определен. Ниже дан пример команд T-SQL, удаляющих brand_type из базы данных model. (Напомним, что если вы создали этот тип данных в пользовательской базе данных и хотите, чтобы в Enterprise Manager было видно, что этот тип данных был удален, то выберите в Enterprise Manager команду Refresh в меню Action.)
USE model GO sp_droptype brand_type GO
Давайте вернемся к нашему примеру базы данных. Мы создадим заново таблицу Product_Info, пользуясь новым пользовательским типом brand_type, а затем создадим таблицу Brands. Эта таблица, как и таблица Product_Info, будет иметь колонку Brand_ID и мы применим для этих колонок одинаковый brand_type. Сначала нам надо будет удалить старую таблицу Product_Info, чтобы мы смогли бы создать ее снова. Ниже показан код, который выполнит все необходимые действия:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID brand_type ) GO CREATE TABLE Brands ( Brand_ID brand_type, Brand_Name char(30), Supplier_ID smallint ) GO
Задав одинаковый тип данных brand_type для колонок Brand_ID в обеих таблицах, мы гарантируем одинаковость атрибутов обеих колонок. Нам не надо помнить об особенностях типа данных, на котором основывается тип данных brand_type, мы можем просто применять новый тип данных для всех колонок Brand_ID.
Кто же должен следить за этими
При помощи SQL Server вы можете задать, в какой именно группе файлов будут размещаться те или иные таблицы и данные из этих таблиц (если вы создали одну или несколько пользовательских групп файлов). Если при создании таблицы группа файлов не была задана, то таблицы будут размещаться в первичной группе файлов, если только другая группа файлов не будет задана в качестве применяемой по умолчанию. (Группы файлов применяются для размещения файлов и индексов на заданных дисках или массивах дисков. Более подробно о них и о том, как и зачем таблицы данных размещаются в файлах и в группах файлов, было рассказано в лекции 9.)
Предположим, что в созданной нами базе данных MyDB имеется группа файлов с именем product_group, содержащая один
USE master
GO
CREATE DATABASE MyDB
ON PRIMARY -- Явное задание первичной
-- группы файлов (не обязательно)
(NAME = MyDBroot, -- Первичный файл данных
FILENAME = 'c:\mssql2k\MSSQL\data\mydbroot.mdf',
SIZE = 8MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB),
FILEGROUP product_group -- Группа файлов для следующего файла
(NAME = MyDBdata1, -- Вторичный файл данных
FILENAME = 'e:\mssql2k\MSSQL\data\mydbdata1.ndf',
SIZE = 1000MB,
MAXSIZE = 1500MB,
FILEGROWTH = 100MB)
LOG ON
(NAME = Logdata1, -- Файл журнала
FILENAME = 'f:\log_files\logdata1.ldf',
SIZE = 1000MB,
MAXSIZE = 1500MB,
FILEGROWTH = 100MB)
GO
А теперь мы можем создать таблицу Product_Info в группе файлов product_group, пользуясь командой CREATE TABLE, как показано ниже.
USE MyDB GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID brand_type ) on product_group GO
Таблица и все данные, которые будут вставлены в таблицу, разместятся на диске E, диске, на котором была задана группа файлов product_group. Поэтому данные из таблицы Product_Info будут иметь свой дисковый накопитель, предназначенный для их ввода-вывода до тех пор, пока в этой же группе файлов не будут созданы другие таблицы.
Null-значение (null value) – это неизвестное значение, для которого применяется обозначение NULL. Способность хранить null-значения (nullability) – это свойство, благодаря которому колонка способна либо хранить null -значения, либо отвергать их. Null -значение в колонке обычно означает, что для данной строки этой колонки нет данных, потому что значение неизвестно, либо не имеет смысла, либо не задано или будет задано в будущем. Null -значения – это не пустые значения и не значения числа 0, их настоящие значения неизвестны (unknown), поэтому никакие два null -значения не являются равными.
Колонки, способные хранить null -значения, могут оказаться полезными в случаях, когда необходимая информация пока что недоступна для вас (это может быть, например, инициал для среднего имени покупателей). Что должно храниться в этой колонке для записи о некотором покупателе, который не имеет среднего имени, и поэтому не имеет среднего инициала? Если в этой колонке разрешено применять значения NULL, то null -значение будет правильным выбором и будет иметь смысл – благодаря этому вы поймете, что информация из данной колонки не имеет смысла.
Как правило, не следует применять null -значения. Из-за них запросы и обновления становятся более сложными, кроме того, к колонкам, способным хранить null -значения, нельзя применять некоторые настройки, такие как первичные ключи и свойство IDENTITY.
Прекрасной альтернативой применению null -значений в колонке является задание значения по умолчанию (default value) для этой колонки. Если значение не было задано при вводе строки, то в колонку записывается значение по умолчанию. (Более подробно о применении значений по умолчанию написано в лекции 16.) Если вы определите эту колонку, как способную хранить null -значения, т.е. два случая, когда колонка получит значение NULL:
null -значения, то SQL Server присвоит колонке значение NULL (если только для этой колонки не было задано значение по умолчанию).Давайте вернемся к нашему примеру с таблицей Product_Info и зададим для каждой колонки возможность хранить null -значения. Если вы хотите, чтобы в колонке разрешалось хранить null -значения, то после типа данных надо добавить слово NULL. Если вы не хотите, чтобы разрешалось хранить null -значения, то после типа данных надо добавить слово NOT NULL. Мы рекомендуем всегда указывать, разрешается ли хранить в колонке null -значения, за исключением лишь случаев, когда применяются NULL или с NOT NULL ). Это поможет вам выработать привычку обращать внимание на необходимость способности к хранению null -значений в тех или иных колонках.
null -значения, когда NULL или NOT NULL не заданы, обратитесь к теме "CREATE TABLE" в Books Online и, пользуясь "прокруткой", перейдите к разделу "Nullability Rules Within a Table Definition" (Задание таблиц: правила, определяющие способность к хранению null -значений). Явное задание NULL или NOT NULL будет иметь преимущество по отношению к этим правилам.Пускай в нашем примере с таблицей Product_Info null -значения будет разрешено применять только в колонке для описаний продуктов. Мы не указали способность к хранению null-значений для типа данных brand_type, так как его способность к хранению null -значений уже была задана (как NOT NULL ) при создании этого пользовательского типа данных. Новый оператор CREATE TABLE будет выглядеть так:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint NOT NULL, Product_Name char(20) NOT NULL, Description char(30) NULL, Price smallmoney NOT NULL, Brand_ID brand_type ) GO
Теперь, если описание продукта (Description) не будет задано, а значения остальных четырех полей – заданы, то в таблицу будет введена новая строка со значением NULL для элемента данных, находящегося в колонке Description. Вы должны будете ввести значения для четырех остальных колонок, не допускающих ввода значений NULL (колонок Product_ID, Product_Name, Price и Brand_ID ). Если данные для какой-либо из этих колонок не ввести, то попытка ввести новую строку будет неуспешной.
Когда вы создаете таблицу, вы можете задать одну из колонок как идентифицирующую колонку (identity column), добавив к определению колонки свойство IDENTITY. Если колонка создается со свойством IDENTITY, то SQL Server автоматически генерирует для этой колонки значение строки, рассчитываемое по начальному значению (Product_ID. Если вы разрешите SQL Server генерировать идентифицирующие значения для вводимых строк, то это окажется проще, чем следить за правильностью ввода последовательных значений. Идентифицирующие колонки обычно применяются в
Например, если вы зададите IDENTITY(0, 10), то значение идентифицирующей колонки для первой введенной строки будет равно 0, для второй строки будет равно 10, для третьей строки – 20, и т.д. Если начальное значение или приращение не задать, то для них будут применяться значения по умолчанию, равные 1 и 1. Вы можете задать как оба этих параметра, так и один из них. Идентифицирующие колонки не могут содержать значения по умолчанию и для них не разрешено применение null -значений. В каждой из таблиц может иметься только одна идентифицирующая колонка.
По умолчанию, непосредственный ввод данных в идентифицирующие колонки невозможен и они не могут быть изменены. Если вы хотите повторить ввод удаленной строки и хотите сохранить старое идентифицирующее значение этой строки, то вы можете преодолеть стандартные настройки, применив такой оператор:
SET IDENTITY_INSERT имя_таблицы ON
При помощи этого оператора можно вставить строку и назначить нужное вам значение идентифицирующей колонки. Закончив ввод строки, нужно отменить возможность вставки в идентифицирующую колонку при помощи такого оператора:
SET IDENTITY_INSERT имя_таблицы OFF
После этого, SQL Server, в качестве начального значения, применяемого при добавлении следующих строк, возьмет самое большое значение из данной колонки.
Давайте добавим свойство IDENTITY в таблицу Product_Info. Вместо того, чтобы вводить данные в колонку Product_ID , мы сделаем ее идентифицирующей колонкой, и пусть SQL Server автоматически генерирует ее значения, обеспечивая их уникальность. Ниже показан код T-SQL, который создаст такую таблицу:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint IDENTITY(1, 1) NOT NULL, Product_Name char(20) NOT NULL, Description char(30) NULL, Price smallmoney NOT NULL, Brand_ID brand_type ) GO
Колонка Product_ID теперь будет получать значения, начинающиеся с 1 и имеющие приращение 1 для каждой последующей строки, вставляемой в таблицу. Благодаря свойству IDENTITY, гарантируется, что каждому продукту будет назначено уникальное число-идентификатор, без необходимости какого-либо ввода со стороны пользователя. Выбор числа 1 в качестве приращения является произвольным. Какое бы приращение вы не применили, идентифицирующее значение будет уникальным.
Теперь, когда вы понимаете основные элементы, относящиеся к созданию таблиц при помощи SQL Server, давайте разберем пример создания таблицы при помощи Enterprise Manager. Однако прежде чем начать этот процесс, вы обязательно должны помнить, что проектирование всех ваших таблиц баз данных и их взаимоотношений должно производиться до того, как вы приступите к их фактическому созданию. Для создания таблицы базы данных с помощью SQL Server Enterprise Manager выполните следующие действия.
null -значения.В этой лекции вы изучили основы создания таблиц, научились применять и задавать типы данных, размещать таблицы в группах файлов, применять null -значения и добавлять свойство IDENTITY. Желательно привести таблицы в их окончательную форму до того, как вы будете заполнять их данными. В лекции 15 показаны несколько способов для изменения таблиц при помощи T-SQL. В нескольких следующих лекциях вы узнаете об инсталляции и настройке сети и о Microsoft Cluster Server. Эти лекции помогут вам выполнить завершающие стадии настройки SQL Server.
После того как вы создали базу данных (с файлами и группами файлов), следующим шагом должно стать создание таблиц. Таблицы являются объектами, при помощи которых вы организовываете и храните свои данные. В этой лекции мы расскажем о главных решениях, принимаемых при создании таблиц базы данных. Так как возможны многие варианты настроек, то создание таблиц базы данных может оказаться несколько сложным процессом. Сначала мы рассмотрим основные требования к таблицам, а затем изучим некоторые настройки, сопровождая наше изложение примерами.
В данной лекции вы познакомитесь с системными и null -значения и свойство IDENTITY. Вы также научитесь создавать таблицы при помощи Enterprise Manager и команд Transact SQL (T-SQL). Мы также вкратце затронем здесь другие важные вопросы, относящиеся к созданию таблиц, такие как ограничения, значения по умолчанию и индексы, о которых будет рассказано более подробно в последующих лекциях.
Когда вы приступите к проектированию своих таблиц базы данных, вам потребуется принять некоторые решения, относящиеся к их структуре. К этим решениям относится определение того, какие элементы данных должны храниться в этих таблицах и как таблицы будут связаны друг с другом. Эта работа поможет представить общую картину базы данных, прежде чем вы углубитесь в создание таблиц. Ниже дан перечень этих глобальных решений:
Постарайтесь найти ответы на как можно большее количество этих вопросов о проектировании системы и записать их на листок бумаги или в компьютерной программе для рисования схем, чтобы осознать общую конструкцию таблиц вашей базы данных, прежде чем начать создавать их. Нужно также узнать у ваших пользователей, каким образом будут осуществляться доступ к данным. Например, можно узнать, что некоторая таблица будет предназначена только для чтения или же будут производиться вставки, удаления или обновления данных. Узнайте, какие запросы будут выполняться чаще всего и из каких колонок будут извлекаться данные. Определите, какая информация действительно необходима для базы данных, а какую хранить не надо. Ответы на эти вопросы помогут вам принять решения о том, как создавать таблицы и индексы, какие ограничения могут применяться, какие значения по умолчанию могут оказаться полезными и т.д. А теперь давайте научимся создавать таблицы на основе этого "фундамента".
В данном разделе вы познакомитесь с некоторыми простыми, но важными понятиями, относящимися к таблицам. Мы рассмотрим пример базы данных, в котором вы познакомитесь с основными элементами таблиц и узнаете о системных типах данных и о том, как создавать и удалять
Таблица – это объект базы данных, который хранит данные в виде совокупности строк и колонок. Таблица определяется содержащимися в ней колонками. Данные организованы в форме, похожей на электронные таблицы Excel (см. пример таблицы Product_Info, показанный в табл. 10.1). Таблица Product_Info, используемая в наших примерах, будет создана в базе данных MyDB.
Таблица Product_Info применяется для хранения информации обо всех продуктах, продаваемых в магазине. Когда продукт становится готов к продаже, данные о нем добавляются в новую строку таблицы Product_Info. Эта таблица состоит из пяти колонок: Product_ID (Идентификатор продукта), Product_Name (Название продукта), Description (Описание), Price (Цена) и Brand_ID (Название торговой марки). В табл. 10.1 показаны в качестве примера три строки данных из таблицы Product_Info. Оператор T-SQL, применявшийся для создания этой таблицы (пустой, без данных) показан в разделе "Создание таблицы Product_Info с использованием системных типов данных" далее в этой лекции. (Об использовании оператора INSERT, применяемого для вставки данных в таблицы см. лекцию 20.)
| Product_ID | Product_Name | Description | Price | Brand_ID |
|---|---|---|---|---|
| 1 | Пятифутовый тент | Для одного-двух человек | 80.00 | 12 |
| 2 | Мини-печь | Работает на керосине | 20.00 | 33 |
| 3 | Рюкзак | Со стальным каркасом | 60.00 | 15 |
Мы вернемся к этому примеру таблицы базы данных в этой лекции, когда будем объяснять более сложные вопросы создания таблиц. Но сначала мы продолжим рассказ об основах, которые вы должны знать, чтобы уметь создавать таблицы.
Чтобы задать таблицу, вы должны решить, сколько колонок она будет иметь и данные каких типов (например, символьные или числовые) смогут храниться в каждой из колонок. Вы должны также задать допустимый диапазон для этих данных, например, вы можете разрешить использовать не более 30 символов или числа, хранимые в 4 байтах. Эти атрибуты задаются благодаря тому, что каждой колонке присваивается некоторый тип данных, являющийся набором атрибутов, определяющих тип и диапазон данных, способных храниться в этой колонке. Вы можете пользоваться многими системными типами данных, имеющимися в SQL Server, а можете создать и свой собственный тип данных, основанный на системных типах данных. (Вы не можете изменять системные типы данных, но можете создавать совершенно новые типы данных.)
Как мы уже говорили, вы задаете тип данных для каждой колонки таблицы. При задании типа данных у колонки задаются следующие атрибуты:
Типы данных могут также применяться к колонкам для представлений, параметров в хранимых процедурах и в функциях T-SQL, возвращающих одно или несколько значений данных. bigint, sql_variant и table. (Кроме нескольких исключений, явно указанных в табл. 10.2, для всех указанных объектов применяются те же самые типы данных.)
| Тип данных | Описание | Сколько места занимает |
|---|---|---|
tinyint |
Целочисленные данные в диапазоне от 0 до 255. | 1 байт |
unique-identifier |
Хранит 16-байтное двоичное значение, являющееся глобальным уникальным идентификатором (GUID) | 16 байт |
varbinary |
Двоичные данные переменной длины, состоящие из n байтов, где n может принимать значение от 1 до 8000. Применяйте тип varbinary, если предполагаете, что элементы данных, хранимые в колонке, будут сильно отличаться по своим размерам | Фактическая длина введенных данных плюс 4 байта |
varchar[(n)] |
Данные переменной длины не в кодировке Unicode, длиной в n символов, где n может принимать значение от 1 до 8000 | Фактическая длина введенных данных |
При создании таблиц важно правильно выбрать типы данных для каждой из колонок. Наверное, вы хотели бы, чтобы позволялось хранить нужные данные, но не разрешалось хранить недопустимые данные (например, символьное значение в колонке для числовых данных). Эта забота и решается благодаря типам данных. При выборе типа данных вам полезно ответить на два следующих вопроса:
Выбор подходящего типа данных является довольно понятным процессом. Данные, которые будут вводиться в колонку, должны соответствовать типу данных, заданному для этой колонки. Поэтому вам следует выбрать такой тип данных, который лучше всего охватит диапазон значений, которые могли бы храниться в колонке для всего срока эксплуатации вашего приложения, и в то же время стремясь ограничить ненужный расход места на диске. Ненужный расход места на диске – это место на диске, выделенное для элементов данных, хранящихся в колонке, но не используемое. Например, предположим, у вас есть колонка, в которой нужно хранить одно целое число в диапазоне от 1 до 100. Очевидно, что эти значения могут храниться в типе integer, но каждое целое число типа integer занимает 4 байта. Данные с типом tinyint могут хранить значения от 0 до 255 и для них нужен только 1 байт места. В данном случае tinyint будет наилучшим выбором, потому что это экономит место на диске, необходимое для хранения данных из таблиц.
Затем вы должны определить, какой тип данных следует использовать – с фиксированной либо с переменной длиной. Если все значения данных из колонки будут иметь приблизительно одинаковые размеры, то более эффективным станет применение типа данных с фиксированной длиной, так как обработка данных, имеющих типы переменной длины, вызывает повышенную нагрузку. Вообще говоря, типы данных с переменной длиной следует применять, только если вы предполагаете значительные различия в длине данных, хранимых в данной колонке, и когда данные из колонки обновляются редко. К данным с переменной длиной относятся varchar, nvarchar, varbinary, text, ntext и image.Применение типов данных с переменной длиной может привести к значительной экономии места для хранения данных. Например, если вы зададите тип данных с фиксированной длиной, достаточной для хранения значений в колонке с наибольшей возможной длиной, то для всех значений, занимающих меньше места, истратиться столько же места, как и для этого самого объемного значения. Результатом этого станут огромный ненужный расход места на диске, потому что лишь немногие строки будут расходовать все максимально допустимое место для данных. В большинстве строк будет использовано меньше места, а все неиспользуемое место станет потерянным. А если вы зададите, что будет применяться тип данных с переменной длиной, то короткие значения будут расходовать лишь то место, которое им действительно нужно. Но опять-таки, применение типов данных с переменной длиной повышает нагрузку на процессор. Поэтому, если вам не требуется тип данных с переменной длиной, то применяйте тип данных с фиксированной длиной. Если из соображений расходования места для хранения данных нужно применять тип данных с переменной длиной, то, конечно, применяйте его.
Итак, как же выбрать нужные для ваших таблиц типы данных и их длины? Следуйте уже принятым ранее основным решениям и делайте выбор, который наилучшим образом будет соответствовать потребностям вашего приложения. Вообще говоря, определяясь с размерами колонок таблиц, старайтесь не тратить зря место на диске и не забывайте о потребностях в будущем.
Прежде чем продолжить наше изложение, давайте рассмотрим T-SQL-оператор CREATE TABLE, которую можно применить для создания таблицы Product_Info, показанной в этой лекции ранее в табл. 10.1. В этом примере мы применим только системные типы данных и колонки с фиксированной длиной. Когда вы создаете таблицу при помощи оператора T-SQL, она создается в базе данных, которой вы пользуетесь в текущий момент. Если вы хотите создать таблицу в какой-либо конкретной базе данных, то надо применить оператор USE имя_базы_данных, как показано в примере кода (в нашем примере база данных имеет имя MyDB). Ключевое слово GO означает, что все предыдущие операторы должны быть теперь выполнены. (Об использовании T-SQL см. лекцию 13.)
USE MyDB GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID smallint ) GO
Давайте посмотрим, что произойдет при исполнении этого кода. После оператора CREATE TABLE следует спецификация таблицы с именем Product_Info. Между открывающей и закрывающей скобками заданы имена колонок и их типы данных. Длины для двух типов данных заданы равными 20 и 30, потому что большинство названий продуктов уместятся в 20 символов, а большинство описаний продуктов уместятся в 30 символов. Для Product_ID и Brand_ID применяется тип данных , а не tinyint, потому что мы предполагаем, что количество разновидностей как продуктов, так и торговых марок, превысит 255 (максимальное значение для типа tinyint ), хотя и будет меньше, чем 32767 (максимальное значение для типа ). Так как значения больше, чем 32767, нам не понадобятся, то при использовании типа int мы напрасно тратили бы место на диске.
Пользовательские типы данных (типы данных, задаваемые пользователями,
Например, предположим, что у нас имеется еще одна таблица, с именем Brands (торговые марки) в той же базе данных, в которой находится таблица Product_Info. Пусть в таблице Brands имеется колонка Brand_ID, соответствующая колонке Brand_ID таблицы Product_Info. Пусть в таблице Brands хранятся названия торговых марок и другая информация, относящаяся к торговым маркам. Чтобы гарантировать, что колонки Brand_ID в обеих таблицах имеют одинаковый тип данных и не допускают null -значений, вы можете создать , или же tinyint, или было ли позволено применять null -значения. Если создать тип данных с понятными именем, то вам не придется беспокоиться о правильности применяемых атрибутов, и вы получите гарантию согласованности данных для всех таблиц.
Вы можете пожелать создать типы данных для таких данных, как телефонные номера, почтовые индексы, номера социального страхования и для любых других данных, которые вы можете четко определить и которые применяются более чем в одной таблице базы данных. При создании типа данных вы должны задать следующую информацию:
null -значений в данном типе данных, т.е., позволяет ли он хранить null -значения (null values). (См. раздел "Применение null-значений" далее в этой лекции.)Как только вы определитесь с этим, можно будет создать тип данных. Для создания пользовательского типа данных с помощью Enterprise Manager выполните следующие действия.
brand_type (рис. 10.2).null -значения, то установите флажок Allow NULLs. (См. раздел "Применение null-значений" далее в этой лекции.)Если вы создали когда-то
В поле-списке в левой части диалогового окна Dependencies показаны объекты базы данных, которые зависят от вашего пользовательского типа данных, а в поле-списке в правой части диалогового окна показаны объекты, от которых зависит ваш

(рис 10.4) Папка User Defined Data Types (Пользовательские типы данных)(рис 10.3) Диалоговое окно Drop Objects (Удалить объекты)
(рис 10.6) Диалоговое окно Dependencies (Зависимости)(рис 10.5) Сообщение об ошибке, появляющееся при попытке удалить тип данных, находящийся в использованииСистемная хранимая процедура sp_addtype является командой T-SQL, применяемой для создания USE имя_базы_данных.) Ниже дан пример команд T-SQL, создающих brand_type в базе данных model:
USE model GO sp_addtype brand_type, 'smallint', 'NOT NULL' GO
Три параметра у sp_addtype – это имя пользовательского типа данных, системный тип данных, на котором основывается новый тип данных и возможность использования null -значений в новом типе данных. Новый тип данных, brand_type, появится во всех вновь создаваемых пользовательских базах данных. Если вы создадите Refresh в меню Action Enterprise Manager’а.
Чтобы удалить ненужный sp_droptype в базе данных, в которой этот тип данных был определен. Ниже дан пример команд T-SQL, удаляющих brand_type из базы данных model. (Напомним, что если вы создали этот тип данных в пользовательской базе данных и хотите, чтобы в Enterprise Manager было видно, что этот тип данных был удален, то выберите в Enterprise Manager команду Refresh в меню Action.)
USE model GO sp_droptype brand_type GO
Давайте вернемся к нашему примеру базы данных. Мы создадим заново таблицу Product_Info, пользуясь новым пользовательским типом brand_type, а затем создадим таблицу Brands. Эта таблица, как и таблица Product_Info, будет иметь колонку Brand_ID и мы применим для этих колонок одинаковый brand_type. Сначала нам надо будет удалить старую таблицу Product_Info, чтобы мы смогли бы создать ее снова. Ниже показан код, который выполнит все необходимые действия:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID brand_type ) GO CREATE TABLE Brands ( Brand_ID brand_type, Brand_Name char(30), Supplier_ID smallint ) GO
Задав одинаковый тип данных brand_type для колонок Brand_ID в обеих таблицах, мы гарантируем одинаковость атрибутов обеих колонок. Нам не надо помнить об особенностях типа данных, на котором основывается тип данных brand_type, мы можем просто применять новый тип данных для всех колонок Brand_ID.
Кто же должен следить за этими
При помощи SQL Server вы можете задать, в какой именно группе файлов будут размещаться те или иные таблицы и данные из этих таблиц (если вы создали одну или несколько пользовательских групп файлов). Если при создании таблицы группа файлов не была задана, то таблицы будут размещаться в первичной группе файлов, если только другая группа файлов не будет задана в качестве применяемой по умолчанию. (Группы файлов применяются для размещения файлов и индексов на заданных дисках или массивах дисков. Более подробно о них и о том, как и зачем таблицы данных размещаются в файлах и в группах файлов, было рассказано в лекции 9.)
Предположим, что в созданной нами базе данных MyDB имеется группа файлов с именем product_group, содержащая один
USE master
GO
CREATE DATABASE MyDB
ON PRIMARY -- Явное задание первичной
-- группы файлов (не обязательно)
(NAME = MyDBroot, -- Первичный файл данных
FILENAME = 'c:\mssql2k\MSSQL\data\mydbroot.mdf',
SIZE = 8MB,
MAXSIZE = 10MB,
FILEGROWTH = 1MB),
FILEGROUP product_group -- Группа файлов для следующего файла
(NAME = MyDBdata1, -- Вторичный файл данных
FILENAME = 'e:\mssql2k\MSSQL\data\mydbdata1.ndf',
SIZE = 1000MB,
MAXSIZE = 1500MB,
FILEGROWTH = 100MB)
LOG ON
(NAME = Logdata1, -- Файл журнала
FILENAME = 'f:\log_files\logdata1.ldf',
SIZE = 1000MB,
MAXSIZE = 1500MB,
FILEGROWTH = 100MB)
GO
А теперь мы можем создать таблицу Product_Info в группе файлов product_group, пользуясь командой CREATE TABLE, как показано ниже.
USE MyDB GO CREATE TABLE Product_Info ( Product_ID smallint, Product_Name char(20), Description char(30), Price smallmoney, Brand_ID brand_type ) on product_group GO
Таблица и все данные, которые будут вставлены в таблицу, разместятся на диске E, диске, на котором была задана группа файлов product_group. Поэтому данные из таблицы Product_Info будут иметь свой дисковый накопитель, предназначенный для их ввода-вывода до тех пор, пока в этой же группе файлов не будут созданы другие таблицы.
Null-значение (null value) – это неизвестное значение, для которого применяется обозначение NULL. Способность хранить null-значения (nullability) – это свойство, благодаря которому колонка способна либо хранить null -значения, либо отвергать их. Null -значение в колонке обычно означает, что для данной строки этой колонки нет данных, потому что значение неизвестно, либо не имеет смысла, либо не задано или будет задано в будущем. Null -значения – это не пустые значения и не значения числа 0, их настоящие значения неизвестны (unknown), поэтому никакие два null -значения не являются равными.
Колонки, способные хранить null -значения, могут оказаться полезными в случаях, когда необходимая информация пока что недоступна для вас (это может быть, например, инициал для среднего имени покупателей). Что должно храниться в этой колонке для записи о некотором покупателе, который не имеет среднего имени, и поэтому не имеет среднего инициала? Если в этой колонке разрешено применять значения NULL, то null -значение будет правильным выбором и будет иметь смысл – благодаря этому вы поймете, что информация из данной колонки не имеет смысла.
Как правило, не следует применять null -значения. Из-за них запросы и обновления становятся более сложными, кроме того, к колонкам, способным хранить null -значения, нельзя применять некоторые настройки, такие как первичные ключи и свойство IDENTITY.
Прекрасной альтернативой применению null -значений в колонке является задание значения по умолчанию (default value) для этой колонки. Если значение не было задано при вводе строки, то в колонку записывается значение по умолчанию. (Более подробно о применении значений по умолчанию написано в лекции 16.) Если вы определите эту колонку, как способную хранить null -значения, т.е. два случая, когда колонка получит значение NULL:
null -значения, то SQL Server присвоит колонке значение NULL (если только для этой колонки не было задано значение по умолчанию).Давайте вернемся к нашему примеру с таблицей Product_Info и зададим для каждой колонки возможность хранить null -значения. Если вы хотите, чтобы в колонке разрешалось хранить null -значения, то после типа данных надо добавить слово NULL. Если вы не хотите, чтобы разрешалось хранить null -значения, то после типа данных надо добавить слово NOT NULL. Мы рекомендуем всегда указывать, разрешается ли хранить в колонке null -значения, за исключением лишь случаев, когда применяются NULL или с NOT NULL ). Это поможет вам выработать привычку обращать внимание на необходимость способности к хранению null -значений в тех или иных колонках.
null -значения, когда NULL или NOT NULL не заданы, обратитесь к теме "CREATE TABLE" в Books Online и, пользуясь "прокруткой", перейдите к разделу "Nullability Rules Within a Table Definition" (Задание таблиц: правила, определяющие способность к хранению null -значений). Явное задание NULL или NOT NULL будет иметь преимущество по отношению к этим правилам.Пускай в нашем примере с таблицей Product_Info null -значения будет разрешено применять только в колонке для описаний продуктов. Мы не указали способность к хранению null-значений для типа данных brand_type, так как его способность к хранению null -значений уже была задана (как NOT NULL ) при создании этого пользовательского типа данных. Новый оператор CREATE TABLE будет выглядеть так:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint NOT NULL, Product_Name char(20) NOT NULL, Description char(30) NULL, Price smallmoney NOT NULL, Brand_ID brand_type ) GO
Теперь, если описание продукта (Description) не будет задано, а значения остальных четырех полей – заданы, то в таблицу будет введена новая строка со значением NULL для элемента данных, находящегося в колонке Description. Вы должны будете ввести значения для четырех остальных колонок, не допускающих ввода значений NULL (колонок Product_ID, Product_Name, Price и Brand_ID ). Если данные для какой-либо из этих колонок не ввести, то попытка ввести новую строку будет неуспешной.
Когда вы создаете таблицу, вы можете задать одну из колонок как идентифицирующую колонку (identity column), добавив к определению колонки свойство IDENTITY. Если колонка создается со свойством IDENTITY, то SQL Server автоматически генерирует для этой колонки значение строки, рассчитываемое по начальному значению (Product_ID. Если вы разрешите SQL Server генерировать идентифицирующие значения для вводимых строк, то это окажется проще, чем следить за правильностью ввода последовательных значений. Идентифицирующие колонки обычно применяются в
Например, если вы зададите IDENTITY(0, 10), то значение идентифицирующей колонки для первой введенной строки будет равно 0, для второй строки будет равно 10, для третьей строки – 20, и т.д. Если начальное значение или приращение не задать, то для них будут применяться значения по умолчанию, равные 1 и 1. Вы можете задать как оба этих параметра, так и один из них. Идентифицирующие колонки не могут содержать значения по умолчанию и для них не разрешено применение null -значений. В каждой из таблиц может иметься только одна идентифицирующая колонка.
По умолчанию, непосредственный ввод данных в идентифицирующие колонки невозможен и они не могут быть изменены. Если вы хотите повторить ввод удаленной строки и хотите сохранить старое идентифицирующее значение этой строки, то вы можете преодолеть стандартные настройки, применив такой оператор:
SET IDENTITY_INSERT имя_таблицы ON
При помощи этого оператора можно вставить строку и назначить нужное вам значение идентифицирующей колонки. Закончив ввод строки, нужно отменить возможность вставки в идентифицирующую колонку при помощи такого оператора:
SET IDENTITY_INSERT имя_таблицы OFF
После этого, SQL Server, в качестве начального значения, применяемого при добавлении следующих строк, возьмет самое большое значение из данной колонки.
Давайте добавим свойство IDENTITY в таблицу Product_Info. Вместо того, чтобы вводить данные в колонку Product_ID , мы сделаем ее идентифицирующей колонкой, и пусть SQL Server автоматически генерирует ее значения, обеспечивая их уникальность. Ниже показан код T-SQL, который создаст такую таблицу:
USE MyDB GO DROP TABLE Product_Info GO CREATE TABLE Product_Info ( Product_ID smallint IDENTITY(1, 1) NOT NULL, Product_Name char(20) NOT NULL, Description char(30) NULL, Price smallmoney NOT NULL, Brand_ID brand_type ) GO
Колонка Product_ID теперь будет получать значения, начинающиеся с 1 и имеющие приращение 1 для каждой последующей строки, вставляемой в таблицу. Благодаря свойству IDENTITY, гарантируется, что каждому продукту будет назначено уникальное число-идентификатор, без необходимости какого-либо ввода со стороны пользователя. Выбор числа 1 в качестве приращения является произвольным. Какое бы приращение вы не применили, идентифицирующее значение будет уникальным.
Теперь, когда вы понимаете основные элементы, относящиеся к созданию таблиц при помощи SQL Server, давайте разберем пример создания таблицы при помощи Enterprise Manager. Однако прежде чем начать этот процесс, вы обязательно должны помнить, что проектирование всех ваших таблиц баз данных и их взаимоотношений должно производиться до того, как вы приступите к их фактическому созданию. Для создания таблицы базы данных с помощью SQL Server Enterprise Manager выполните следующие действия.
null -значения.В этой лекции вы изучили основы создания таблиц, научились применять и задавать типы данных, размещать таблицы в группах файлов, применять null -значения и добавлять свойство IDENTITY. Желательно привести таблицы в их окончательную форму до того, как вы будете заполнять их данными. В лекции 15 показаны несколько способов для изменения таблиц при помощи T-SQL. В нескольких следующих лекциях вы узнаете об инсталляции и настройке сети и о Microsoft Cluster Server. Эти лекции помогут вам выполнить завершающие стадии настройки SQL Server.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.