Создание базы данных и таблиц

Создание и открытие базы данных

С помощью sqlite3 создать или открыть существующую базу данных можно двумя способами. Во-первых, при вызове утилиты sqlite3 в качестве аргумента можно указать имя базы данных. Если БД существует, она будет открыта. Если ее нет, она будет создана и открыта.

./sqlite3 your.db

Во вторых, работая в самой программе, можно выполнить команду

.open your.db 

Выяснить, какая база данных является текущей, можно с помощью команды .databases утилиты sqlite3. Если вы работаете с одной БД, а потом открываете другую, то текущей становится вторая БД.

Открытие баз данных в программе sqlite3

Создание и удаление таблицы

Таблицы базы данных создаются с помощью директивы CREATE TABLE языка SQL. После CREATE TABLE идет имя базы данных, после которого в скобках перечисляются имена столбцов и их тип:

sqlite> CREATE TABLE pages (
   ...> title TEXT,
   ...> url TEXT,
   ...> theme INTEGER,
   ...> num INTEGER);

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

Чтобы увидеть список таблиц базы данных используется команда .tables.

Для удаления целой таблицы из базы данных используется директива DROP TABLE, после которой идет имя удаляемой таблицы.

Создание таблиц

Первичный ключи и автоинкремент

Для реляционных баз данных важно, чтобы каждую запись-строку таблицы можно было однозначно идентифицировать. То есть в таблицах не должно быть полностью совпадающих строк. Записи должны отличаться хотя бы по одному полю.

С этой целью принято создавать дополнительное поле, которое часто называют ID или подобно. В базах данных под Android по соглашению столбец для уникального идентификатора записей называют _id.

sqlite> CREATE TABLE pages (
   ...> _id INTEGER,
   ...> title TEXT,
   ...> url TEXT,
   ...> theme INTEGER,
   ...> num INTEGER);

При таком создании таблицы следить за уникальностью поля _id каждой записи должен будет человек. Для SQLite столбец _id ничем не отличается от любого другого. Мы вполне можем сделать несколько записей с одинаковым ID.

Чтобы исключить возможность ввода одинаковых идентификаторов, столбец ID назначают первичным ключом. PRIMARY KEY – ограничитель, который заставляет СУБД проверять уникальность значения данного поля у каждой добавляемой записи.

sqlite> CREATE TABLE pages (
   ...> _id INTEGER PRIMARY KEY,
   ...> title TEXT,
   ...> url TEXT,
   ...> theme INTEGER,
   ...> num INTEGER);

Если нам не важно, какие конкретно идентификаторы будут записываться в поле _id, а важна только уникальность поля, следует назначить полю еще один ограничитель – автоинкремент – AUTOINCREMENT.

sqlite> CREATE TABLE pages (
   ...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
   ...> title TEXT,
   ...> url TEXT, 
   ...> theme INTEGER,
   ...> num INTEGER);

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

NOT NULL и DEFAULT

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

Однако, добавив ограничитель DEFAULT, вы сможете не указывать значение. DEFAULT задает значение по умолчанию. В результате, когда данные в поле не передаются при добавлении записи, поле заполняется тем, что было указано по умолчанию.

Допустим, в таблице поля url, theme и num не должно быть пустыми. При этом если значение для num не передается, то полю присваивается 0. В этом случае команда для создания таблицы будет такой:

sqlite> CREATE TABLE pages (
   ...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
   ...> title TEXT,
   ...> url TEXT NOT NULL,
   ...> theme INTEGER NOT NULL,
   ...> num INTEGER NOT NULL DEFAULT 0);

Ограничители SQL

С помощью команд .schema и PRAGMA TABLE_INFO() можно посмотреть схему таблицы.

Внешний ключ

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

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

sqlite> CREATE TABLE sections (
   ...> _id INTEGER PRIMARY KEY,
   ...> name TEXT);

Тогда в первой таблице в столбце theme следует хранить номера тем – их ID, взятые из второй таблицы. Это будут внешние ключи, представляющие собой первичные в таблице с разделами. Внешние ключи уникальными не будут, так как разные страницы могут принадлежать к одной той же теме.

sqlite> CREATE TABLE pages (
   ...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
   ...> title TEXT,
   ...> url TEXT NOT NULL,
   ...> theme INTEGER NOT NULL,
   ...> num INTEGER NOT NULL DEFAULT 100,
   ...> FOREIGN KEY (theme) REFERENCES sections(_id)
   ...> );

FOREIGN KEY является ограничителем, так как не дает нам записать в поле столбца theme какое-либо иное значение, которое не встречается в качестве первичного ключа в таблице sections. Однако в SQLite поддержка внешнего ключа по умолчанию отключена. Поэтому, даже назначив столбец внешним ключом, вы сможете записывать в его поля любые значения.

Чтобы включить поддержку внешних ключей в sqlite3, надо выполнить команду PRAGMA foreign_keys = ON;. После этого добавить в таблицу запись, в которой внешний ключ не совпадает ни с одним первичным из другой таблицы, не получится.

Установка внешнего ключа