mirror of
https://github.com/treffynnon/sqlstyle.guide.git
synced 2025-03-09 12:49:51 -05:00
Improve translation and formatting
This commit is contained in:
parent
71ee9a0e3e
commit
9b99520651
1 changed files with 64 additions and 64 deletions
|
@ -4,24 +4,24 @@
|
|||
|
||||
## Предисловие
|
||||
|
||||
Вы можете использовать это руководство целиком, [сделать его форк][fork] или создать своё. Основная идея — определить, какой стиль вам подходит больше, и придерживаться его. Если вы хотите предложить изменение или исправить ошибку, [откройте Issue][issue] или [создайте Pull Request][pull] на GitHub'е.
|
||||
Вы можете использовать это руководство целиком, [сделать его форк][fork] или создать своё на его основе. Цель — определить, какой стиль вам подходит больше, и придерживаться его. Если вы хотите предложить изменение или исправить ошибку, [откройте Issue][issue] или [создайте Pull Request][pull] на GitHub'е.
|
||||
|
||||
Рекомендации, описанные в этом руководстве, совместимы с книгой Джо Селко «[Стиль программирования Джо Селко на SQL][celko-ru]» (оригинал: [SQL Programming Style][celko]). Это, в частности, найдут полезным те, кто уже знаком с этой книгой. Тем не менее автор этого руководства в некоторых аспектах более категоричен, нежели Джо Селко, а в других, напротив, более гибок. И, конечно, нельзя не отметить, что это руководство значительно короче и лаконичнее [книги Селко][celko-ru] — здесь вы не встретите ни весёлых историй из жизни, наглядно объясняющих, как и почему лучше не делать, ни длинных повествований, мотивирующих на использование той или иной рекомендации.
|
||||
Рекомендации, описанные в этом руководстве, во многом пересекаются с описанными в книге Джо Селко «[Стиль программирования Джо Селко на SQL][celko-ru]» (оригинал: [SQL Programming Style][celko]). Это, в частности, найдут полезным те, кто уже знаком с этой книгой. Тем не менее автор этого руководства в некоторых аспектах более категоричен, нежели Джо Селко, а в других, напротив, более гибок. И, конечно, нельзя не отметить, что это руководство значительно короче и лаконичнее [книги Селко][celko-ru] — здесь вы не встретите ни весёлых историй из жизни, наглядно объясняющих, как и почему лучше не делать, ни длинных повествований, мотивирующих на использование той или иной рекомендации.
|
||||
|
||||
Это руководство написано в [формате Markdown][dl-md], что позволяет легко включить его в проект или просто сослаться на него оттуда, что гораздо удобнее, нежели работать с большой бумажной книгой.
|
||||
Руководство написано в [формате Markdown][dl-md], что позволяет легко включить его в проект или просто сослаться на него оттуда, что гораздо удобнее, нежели работать с большой бумажной книгой.
|
||||
|
||||
«SQL: Руководство по стилю» (SQL style guide) за авторством Саймона Холиуэлла (Simon Holywell) лицензируется под лицензией [Creative Commons «Атрибуция — На тех же условиях» 4.0 Всемирная][licence-ru]. Оригинал — [http://www.sqlstyle.guide][sqlstyleguide].
|
||||
«SQL: Руководство по стилю» (SQL style guide) за авторством Саймона Холиуэлла (Simon Holywell) находится под лицензией [Creative Commons «Атрибуция — На тех же условиях» 4.0 Всемирная][licence-ru]. Оригинал — [http://www.sqlstyle.guide][sqlstyleguide].
|
||||
|
||||
## Основные положения
|
||||
|
||||
### Хороший стиль
|
||||
|
||||
* **Идентификаторы и имена**. Осмысленные и в одном стиле.
|
||||
* **Идентификаторы и имена**. Осмысленные и в едином стиле.
|
||||
* **Пробелы и отступы**. Логично расставленные для лучшей читаемости кода.
|
||||
* **Дата и время**. По стандарту [ISO 8601][iso-8601-ru]: `YYYY-MM-DD HH:MM:SS.SSSSS`.
|
||||
* **Функции SQL**. Стандартные вместо специфичных (определяемых поставщиком) для переносимости.
|
||||
* **Дата и время**. Соответствующие стандарту [ISO 8601][iso-8601-ru]: `YYYY-MM-DD HH:MM:SS.SSSSS`.
|
||||
* **Функции SQL**. Стандартные вместо специфичных (определяемых поставщиком) с целью лучшей переносимости.
|
||||
* **Код**. Лаконичный и без излишеств, как например: ненужные кавычки или скобки или неуместное использование оператора `WHERE`.
|
||||
* **Комментарии**. Желательно в [стиле C][c-style-comments-ru] — `/*` (начало) и `*/` (конец). Либо `--` перед комментарием, тогда окончанием будет новая строка.
|
||||
* **Комментарии**. Предпочтительно в [стиле C][c-style-comments-ru] — `/*` (начало) и `*/` (конец). Либо `--` перед комментарием, тогда окончанием будет новая строка.
|
||||
|
||||
```sql
|
||||
SELECT file_hash -- stored ssdeep hash
|
||||
|
@ -38,23 +38,23 @@ UPDATE file_system
|
|||
|
||||
### Плохой стиль
|
||||
|
||||
* **CamelCase**. Тяжело для восприятия.
|
||||
* **Префиксы и [венгерская нотация][hungarian-notation-ru]**. Никаких `sp_` или `tbl`.
|
||||
* **CamelCase**. Неудобочитаем.
|
||||
* **Префиксы и [венгерская нотация][hungarian-notation-ru]**. Префиксы наподобие `sp_` или `tbl_` избыточны.
|
||||
* **Множественное число**. Лучше использовать более естественно звучащие собирательные понятия. Например, `staff` вместо `employees` или `people` вместо `individuals`.
|
||||
* **Идентификаторы в кавычках**. Если они обязательно нужны, тогда используйте двойные кавычки, определённые в стандарте [SQL-92][sql-92-ru] для переносимости (в зависимости от поставщика, возможно, придётся настроить сервер SQL).
|
||||
* **Объектно-ориентированные принципы проектирования**. Не применять к SQL или структуре базы данных.
|
||||
* **Идентификаторы в кавычках**. Если они обязательно нужны, тогда используйте двойные кавычки, определённые в стандарте [SQL-92][sql-92-ru] с целью лучшей переносимости в дальнейшем.
|
||||
* **Принципы объектно-ориентированного проектирования**. Не нужно применять к SQL или структуре базы данных.
|
||||
|
||||
## Соглашения о наименовании
|
||||
|
||||
### Общее
|
||||
|
||||
* Убедитесь в том, что имя уникально и его нет в [списке зарезервированных ключевых слов][reserved-keywords].
|
||||
* Ограничивайте длину имени 30 байтами (это 30 символов, если не используется многобайтовый набор символов).
|
||||
* Начинайте имена с буквы и не заканчивайте их символом подчёркивания.
|
||||
* Используйте в именах только буквы, цифры и символ подчёркивания.
|
||||
* Избегайте нескольких подряд идущих символов подчёркивания.
|
||||
* Используйте символ подчёркивания там, где вы бы поставили пробел в реальной жизни (например, `first name` станет `first_name`).
|
||||
* Избегайте сокращений. Если их всё же нужно использовать, убедитесь в том, что они общепонятны.
|
||||
* **Убедитесь** в том, что имя уникально и его нет в [списке зарезервированных ключевых слов][reserved-keywords].
|
||||
* **Ограничивайте** длину имени 30 байтами (это 30 символов, если не используется многобайтовый набор символов).
|
||||
* **Начинайте** имена с буквы и **не заканчивайте** их символом подчёркивания.
|
||||
* **Используйте** в именах только буквы, цифры и символ подчёркивания.
|
||||
* **Избегайте** нескольких подряд идущих символов подчёркивания.
|
||||
* **Используйте** символ подчёркивания там, где вы бы поставили пробел в реальной жизни (например, `first name` станет `first_name`).
|
||||
* **Избегайте** сокращений. Если их всё же нужно использовать, убедитесь в том, что они общепонятны.
|
||||
|
||||
```sql
|
||||
SELECT first_name
|
||||
|
@ -63,25 +63,25 @@ SELECT first_name
|
|||
|
||||
### Таблицы
|
||||
|
||||
* Используйте собирательные имена или, что менее предпочтительно, форму множественного числа. Например, `staff` и `employees` (в порядке убывания предпочтения).
|
||||
* Не используйте описательные префиксы вида `tbl_` и венгерскую нотацию в целом.
|
||||
* Не допускайте совпадений названия таблицы с любым из её столбцов.
|
||||
* По возможности избегайте объединения названий двух таблиц для построения таблицы отношений. Например, вместо названия `cars_mechanics` лучше подойдёт `services`.
|
||||
* **Используйте** собирательные имена или, что менее предпочтительно, форму множественного числа. Например, `staff` и `employees` (в порядке убывания предпочтения).
|
||||
* **Не используйте** описательные префиксы вида `tbl_` и венгерскую нотацию в целом.
|
||||
* **Не допускайте** совпадений названия таблицы с названием любого из её столбцов.
|
||||
* По возможности **избегайте** объединения названий двух таблиц для построения таблицы отношений. Например, вместо названия `cars_mechanics` лучше подойдёт `services`.
|
||||
|
||||
### Столбцы
|
||||
|
||||
* Используйте всегда в единственном числе.
|
||||
* По возможности не используйте `id` в качестве первичного идентификатора таблицы.
|
||||
* Не создавайте в таблице столбцов с таким же названием, как у неё самой.
|
||||
* Названия всегда пишите со строчной буквы. Могут быть исключения, например использование имени собственного.
|
||||
* Названия всегда **давайте** в единственном числе.
|
||||
* По возможности **не используйте** `id` в качестве первичного идентификатора таблицы.
|
||||
* **Не создавайте** в таблице столбцов с таким же названием, как у неё самой.
|
||||
* Названия **всегда пишите** со строчной буквы. Могут быть исключения, например использование имени собственного.
|
||||
|
||||
### Псевдонимы/корреляции
|
||||
|
||||
* Должны так или иначе быть связаны с объектами или выражениями, псевдонимом которых они являются.
|
||||
* Имя корреляции обычно составляется из первых букв каждого слова в имени объекта.
|
||||
* Добавьте цифру к имени, если такое уже существует.
|
||||
* Всегда используйте ключевое слово `AS` для лучшей читаемости.
|
||||
* Для вычислимых данных (`SUM()` или `AVG()`) используйте такие имена, которые вы бы дали, будь они столбцами в таблице.
|
||||
* **Должны** так или иначе быть связаны с объектами или выражениями, псевдонимом которых они являются.
|
||||
* Имя корреляции **обычно составляется** из первых букв каждого слова в имени объекта.
|
||||
* **Добавьте** цифру к имени, если такое уже существует.
|
||||
* Всегда **используйте** ключевое слово `AS` для лучшей читаемости.
|
||||
* Для вычислимых данных (`SUM()` или `AVG()`) **используйте** такие имена, которые вы бы дали, будь они столбцами в таблице.
|
||||
|
||||
```sql
|
||||
SELECT first_name AS fn
|
||||
|
@ -96,12 +96,12 @@ SELECT SUM(s.monitor_tally) AS monitor_total
|
|||
|
||||
### Хранимые процедуры
|
||||
|
||||
* Имя должно содержать глагол.
|
||||
* Не используйте описательные префиксы вида `sp_` и венгерскую нотацию в целом.
|
||||
* Имя **должно** содержать глагол.
|
||||
* **Не используйте** описательные префиксы вида `sp_` и венгерскую нотацию в целом.
|
||||
|
||||
### Универсальные суффиксы
|
||||
|
||||
Приведённые ниже суффиксы универсальны, что гарантирует простоту понимания значения столбцов из кода SQL. Используйте их, когда это уместно.
|
||||
Приведённые ниже суффиксы универсальны, что гарантирует простоту понимания значения столбцов из кода SQL.
|
||||
|
||||
* `_id` — уникальный идентификатор, например первичный ключ.
|
||||
* `_status` — флаг или любой статус, например `publication_status`.
|
||||
|
@ -120,7 +120,7 @@ SELECT SUM(s.monitor_tally) AS monitor_total
|
|||
|
||||
[Зареервированные ключевые слова][reserved-keywords] всегда пишите прописными буквами, например `SELECT`, `WHERE`.
|
||||
|
||||
Не испольуйте сокращённый вариант ключевого слова, если имеется полный. Например, испольуйте `ABSOLUTE` вместо `ABS`.
|
||||
Не испольуйте сокращённый вариант ключевого слова, если имеется полный. Например, используйте `ABSOLUTE` вместо `ABS`.
|
||||
|
||||
Не испольуйте специфичные для какого-либо поставщика СУБД ключевые слова, если в ANSI SQL есть ключевые слова, выполняющие такие же функции. Это сделает ваш код более переносимым.
|
||||
|
||||
|
@ -132,11 +132,11 @@ SELECT model_num
|
|||
|
||||
### Пробельные символы
|
||||
|
||||
Для лучшей удобочитаемости кода важно правильно использовать различного рода пробельные символы. Не нужно нагромождать код или удалять пробелы, присущие естественному языку.
|
||||
Для лучшей удобочитаемости кода важно правильно использовать пробельные символы. Не нужно нагромождать код или удалять пробелы, присущие естественному языку.
|
||||
|
||||
#### Пробелы
|
||||
|
||||
Можно и нужно использовать пробелы для выравнивания основных ключевых слов по их последнему символу. В типографике получающиеся таким образом «[коридоры][rivers-ru]» стараются избегать, в то же время в нашем случае они, напротив, помогают лучше вычленять важные ключевые слова.
|
||||
Можно и нужно использовать пробелы для выравнивания основных ключевых слов по их правому краю. В типографике получающиеся таким образом «[коридоры][rivers-ru]» стараются избегать, в то же время в нашем случае они, напротив, помогают лучше вычленять важные ключевые слова.
|
||||
|
||||
```sql
|
||||
(SELECT f.species_name,
|
||||
|
@ -226,7 +226,7 @@ SELECT r.last_name
|
|||
|
||||
#### Подзапросы
|
||||
|
||||
Подзапросы тоже должны быть выровнены по правому краю «коридора», а внутри них самих применяются те же правила форматирования, что и в любом другом запросе. Если используются вложенные подзапросы, может быть оправданным постановка закрывающей скобки на новой строке ровно под парной ей открывающей скобкой.
|
||||
Подзапросы тоже должны быть выровнены по правому краю «коридора», а внутри них самих применяются те же правила форматирования, что и в любом другом запросе. Если используются вложенные подзапросы, может иметь смысл поставить закрывающую скобку на новой строке ровно под парной ей открывающей скобкой.
|
||||
|
||||
```sql
|
||||
SELECT r.last_name,
|
||||
|
@ -244,10 +244,10 @@ SELECT r.last_name,
|
|||
|
||||
### Формальные тонкости
|
||||
|
||||
* Используйте `BETWEEN`, где возможно, вместо нагромождения условий `AND`.
|
||||
* Таким же образом старайтесь использовать `IN()` вместо `OR`.
|
||||
* Используйте `CASE`, если значение должно быть интерпретировано до окончания выполнения запроса. С помощью `CASE` можно также формировать сложные логические структуры.
|
||||
* По возможности избегайте использования `UNION` и временных таблиц.
|
||||
* **Используйте** `BETWEEN`, где возможно, вместо нагромождения условий `AND`.
|
||||
* Таким же образом старайтесь **использовать** `IN()` вместо `OR`.
|
||||
* **Используйте** `CASE`, если значение должно быть интерпретировано до окончания выполнения запроса. С помощью `CASE` можно также формировать сложные логические структуры.
|
||||
* По возможности **избегайте** использования `UNION` и временных таблиц.
|
||||
|
||||
```sql
|
||||
SELECT CASE postcode
|
||||
|
@ -268,12 +268,12 @@ SELECT CASE postcode
|
|||
|
||||
### Типы данных
|
||||
|
||||
* По возможности не используйте специфичные для той или иной СУБД типы данных. Это может негативно сказаться на переносимости, а также этих типов может не оказаться в старых версиях этих же СУБД.
|
||||
* Для работы с плавающей точкой используйте только `REAL` или `FLOAT`, но где нет необходимости в подобных вычислениях, всегда предпочитайте использование `NUMERIC` и `DECIMAL` остальным типам. Ошибки округления в операциях с плавающей точкой могут оказаться очень некстати.
|
||||
* По возможности **не используйте** специфичные для той или иной СУБД типы данных. Это может негативно сказаться на переносимости, а также этих типов может не оказаться в старых версиях этих же СУБД.
|
||||
* Для работы с плавающей точкой **используйте** только `REAL` или `FLOAT`, но где нет необходимости в подобных вычислениях, всегда **используйте** `NUMERIC` и `DECIMAL`. Ошибки округления в операциях с плавающей точкой могут оказаться очень некстати.
|
||||
|
||||
### Значения по умолчанию
|
||||
|
||||
* Значение по умолчанию всегда должно совпадать по типу со столбцом. Если, скажем, столбец объявлен как `DECIMAL`, не нужно в качестве умолчания указывать значение типа `INTEGER`.
|
||||
* Значение по умолчанию всегда должно **совпадать** по типу со столбцом. Если, скажем, столбец объявлен как `DECIMAL`, не нужно в качестве умолчания указывать значение типа `INTEGER`.
|
||||
* Значения по умолчанию должны располагаться **после** объявления типа столбца и **перед** пометкой `NOT NULL`.
|
||||
|
||||
### Ограничения и ключи
|
||||
|
@ -282,12 +282,12 @@ SELECT CASE postcode
|
|||
|
||||
#### Ключи
|
||||
|
||||
Выбор столбцов, которые будут играть роль ключей, должен быть предельно выверен и оправдан, поскольку от них напрямую зависит производительность и целостность данных.
|
||||
Выбор столбцов, которые будут играть роль ключей, должен быть обоснован и предельно выверен, поскольку от них напрямую зависит производительность и целостность данных.
|
||||
|
||||
1. Ключ должен быть в какой-то степени уникальным.
|
||||
2. Должна быть согласованность по типу данных для значения во всей схеме, а также чем ниже вероятность того, что это изменится в будущем, тем лучше.
|
||||
3. Можно ли проверить значение на соответствие стандарту (например, опубликованному ISO)?
|
||||
4. Ключ должен быть как можно проще, чтобы можно было без дополнительных трудностей использовать составные ключи.
|
||||
3. Можно ли проверить значение на соответствие стандарту (например, ISO)?
|
||||
4. Ключ должен быть как можно проще, чтобы можно было без трудностей использовать составные ключи.
|
||||
|
||||
Это своего рода конвенции, которые нужно сформулировать при проектировании базы данных. Если требования впоследствии будут разрастаться, можно и нужно вносить изменения в структуру базы, чтобы поддерживать её в актуальном состоянии.
|
||||
|
||||
|
@ -297,23 +297,23 @@ SELECT CASE postcode
|
|||
|
||||
##### Общее
|
||||
|
||||
* У каждой таблицы должен быть хотя бы один ключ.
|
||||
* Ограничениям нужно присваивать вразумительные имена. Для `UNIQUE`, `PRIMARY KEY` и `FOREIGN KEY` подобные имена создаются автоматически, поэтому нужно позаботиться об остальных ограничениях.
|
||||
* У каждой таблицы **должен быть** хотя бы один ключ.
|
||||
* Ограничениям нужно **присваивать** вразумительные имена. Для `UNIQUE`, `PRIMARY KEY` и `FOREIGN KEY` подобные имена создаются автоматически, поэтому нужно позаботиться об остальных ограничениях.
|
||||
|
||||
##### Расположение и порядок
|
||||
|
||||
* Первичный ключ должен быть объявлен в самом начале, сразу после оператора `CREATE TABLE`.
|
||||
* Ограничения должны быть объявлены строго ниже столбца, с которым они связаны. Расставьте отступы так, чтобы объявление ограничения начиналось после названия столбца.
|
||||
* В случае ограничений, затрагивающих несколько столбцов, старайтесь объявлять их как можно ближе к описанию последнего из этих столбцов. В крайнем случае объявляйте ограничение в конце тела `CREATE TABLE`.
|
||||
* Ограничения целостности уровня таблицы должны располагаться в конце.
|
||||
* Используйте алфавитный порядок там, где `ON DELETE` предшествует `ON UPDATE`.
|
||||
* Внутри запроса можно выравнивать каждый уровень по-своему. Например, можно добавить отступы после названия столбцов, чтобы типы данных начинались с одной позиции, а затем ещё добавить отступов в нужном количестве, чтобы все объявления `NOT NULL` тоже были выровнены по левому краю. Подобное форматирование позволит быстрее ориентироваться в коде.
|
||||
* Первичный ключ должен быть **объявлен** в самом начале, сразу после оператора `CREATE TABLE`.
|
||||
* Ограничения должны быть **объявлены** строго ниже столбца, с которым они связаны. Расставьте отступы так, чтобы объявление ограничения начиналось после названия столбца.
|
||||
* В случае ограничений, затрагивающих несколько столбцов, старайтесь **объявлять** их как можно ближе к описанию последнего из них. В крайнем случае объявляйте ограничение в конце тела `CREATE TABLE`.
|
||||
* Ограничения целостности уровня таблицы должны **располагаться** в конце.
|
||||
* **Используйте** алфавитный порядок там, где `ON DELETE` предшествует `ON UPDATE`.
|
||||
* Внутри запроса можно **выравнивать** каждый уровень по-своему. Например, можно добавить отступы после названия столбцов, чтобы типы данных начинались с одной позиции, а затем ещё добавить отступов в нужном количестве, чтобы все объявления `NOT NULL` тоже были выровнены по левому краю. Подобное форматирование позволит быстрее ориентироваться в коде.
|
||||
|
||||
##### Валидация
|
||||
|
||||
* Используйте `LIKE` и `SIMILAR TO` для обеспечения целостности строк с известным форматом.
|
||||
* Если диапазон числовых значений для столбца известен, используйте `CHECK()` для предотвращения внесения в базу некорректных данных или скрытого отсечения части значения слишком больших данных. Обычно проверка делается на то, что значение больше нуля.
|
||||
* `CHECK()` должен быть объявлен как отдельное ограничение для упрощения последующей отладки.
|
||||
* **Используйте** `LIKE` и `SIMILAR TO` для обеспечения целостности строк с известным форматом.
|
||||
* Если диапазон числовых значений для столбца известен, **используйте** `CHECK()` для предотвращения внесения в базу некорректных данных или скрытого отсечения части значения слишком больших данных. Обычно проверка делается на то, что значение больше нуля.
|
||||
* `CHECK()` должен быть **объявлен** как отдельное ограничение для упрощения последующей отладки.
|
||||
|
||||
##### Пример
|
||||
|
||||
|
@ -330,10 +330,10 @@ CREATE TABLE staff (
|
|||
|
||||
### Чего следует избегать
|
||||
|
||||
* Использования объектно-ориентированных принципов, поскольку они далеко не всегда оптимально ложатся на реляционную модель баз данных.
|
||||
* Разнесения по разным столбцам значений и единиц измерения. Нужно создавать столбцы так, чтобы единицы измерения были чем-то самим собой разумеющимся. Для проверки корректности вставляемых в столбец данных используйте `CHECK()`.
|
||||
* Паттерна [EAV (Entity Attribute Value)][eav]. Вместо него используйте специальные продукты, предназначенные для работы с неструктурированными данными.
|
||||
* Разбивки данных, логически принадлежащих одной таблице, по разным таблицам на основании условностей, например архивации по времени или географическим атрибутам данных. Впоследствии для работы с несколькими подобными таблицам придётся часто использовать `UNION` вместо простых запросов к одной таблице.
|
||||
* **Не применяйте** объектно-ориентированные принципы, поскольку они далеко не всегда оптимально ложатся на реляционную модель баз данных.
|
||||
* **Не разносите** по разным столбцам значения и единицы измерения. Нужно создавать столбцы так, чтобы единицы измерения были чем-то самим собой разумеющимся. Для проверки корректности вставляемых в столбец данных используйте `CHECK()`.
|
||||
* **Избегайте** паттерна [EAV (Entity Attribute Value)][eav]. Вместо него используйте специальные продукты, предназначенные для работы с неструктурированными данными.
|
||||
* **Не разбивайте** данные, логически принадлежащие одной таблице, по разным таблицам на основании условностей, например архивации по времени или географическим атрибутам. Впоследствии для работы с несколькими подобными таблицам придётся часто использовать `UNION` вместо простых запросов к одной таблице.
|
||||
|
||||
## Приложение
|
||||
|
||||
|
|
Loading…
Reference in a new issue