Какой стандарт кодирования SQL вы соблюдаете?
Существует ли какой-либо широко используемый стандарт SQL-кодирования? SQL немного отличается от языков программирования типа C/C++. На самом деле не знаю, как лучше отформатировать его для удобства чтения.
14 ответов
Не назвал бы это стандартом кодирования - больше похоже на стиль кодирования
SELECT
T1.col1,
T1.col2,
T2.col3
FROM
table1 T1
INNER JOIN ON Table2 T2 ON T1.ID = T2.ID
WHERE
T1.col1 = 'xxx'
AND T2.Col3 = 'yyy'
- использовать заглавные слова
- основные ключевые слова в новой строке
- не могу привыкнуть к запятым перед столбцами
- всегда используйте короткие значимые псевдонимы таблиц
- префикс просмотров с v
- префикс хранимых процедур с помощью sp (однако не используйте sp_, который зарезервирован для встроенных процедур)
- не добавляйте таблицы к префиксам
- имена таблиц единственного числа
Мне нравится запятая предыдущим способом:
SELECT
column1
, column2
, column3
, COALESCE(column4,'foo') column4
FROM
tablename
WHERE
column1 = 'bar'
ORDER BY
column1
, column2
по моему мнению, это легче всего читать и отлаживать.
Я знаю, что это долго, но терпите меня, это важно. Этот вопрос открыл классную банку с червями. А если вам не нравятся блоки базы данных, читайте дальше.
И, прежде чем кто-либо задумывается о том, чтобы опровергнуть мой ответ, просмотрите следующую статью и связанные с ней статьи о блокировке и перекомпиляции; два наиболее разрушительных попадания ресурсов в базу данных SQL.
http://support.microsoft.com/kb/263889
Я могу печатать довольно быстро, и я не люблю печатать больше, чем следующий человек. Но пункты ниже я следую чрезвычайно внимательно, даже если это больше печатать. Настолько, что я создал свои собственные приложения SP, чтобы сделать это для меня.
Вопросы, которые я привел, действительно важны! Вы могли бы даже сказать себе: "Вы шутите, это не проблема", ну, тогда вы не читали статьи выше. И, совершенно идиотски, что M$ поставил бы эти точки в качестве ЗАМЕЧАНИЙ. Эти вопросы для меня должны быть смелыми и кричать.
Я также много пишу для написания своих основных сценариев с использованием приложений на C# для ускорения разработки, и эти методы очень полезны (на 10 лет), чтобы сделать SP сценариев проще и особенно быстрее.
Есть больше, чем это, но это то, что я делаю для первых 60% всего.
Лучшие практики
- Используйте квадратные скобки вокруг объектов, чтобы механизм запросов явно знал поле, когда видит его
- Используйте ЖЕ СЛУЧАЙ в качестве имен объектов таблицы и имен полей
- При вызове SP из приложения используйте полное имя [dbo].[ProcName] с правильным владельцем и регистр. Без шуток! Читайте статьи выше!
- Ссылка на владельца объекта, так что безопасность явно известна и не должна быть выяснена
- НЕ "sp_", поскольку это относится к системным хранимым процессам и накладным расходам
- Используйте SET NOCOUNT ON и SET NOCOUNT OFF, чтобы устранить дополнительные накладные расходы, чтобы отслеживать, сколько записей обновляется в сохраненном процессе, если они вам не нужны. Обычно это не так, и вы можете значительно увеличить производительность.
предпочтения
- Префикс хранимых процедур с процедурой
- Суффикс каждого сохраненного процесса с помощью SEL, UPD, DEL, INS (или SELECT, UPDATE, DELETE, INSERT)
- Используйте зарезервированные слова
- Основные ключевые слова в новой строке (скриптинг)
- Используйте запятые перед столбцами (скриптинг)
- Префикс просмотра с VW
- Не ставьте таблицы с префиксами
- Названия таблиц единственного числа
- Добавьте суффикс к стандартным именам, таким как "_ByPK", "_OrderByLastName" или "_Top15Orders" для вариантов на стандартном пакете обновления SP.
Выбрать
CREATE PROC [dbo].[procTable_SEL] AS SET NOCOUNT ON SELECT [Column1] = T1.[col1] , [Column2] = T1.[col2] , [Column3] = T2.[col3] FROM [dbo].[Table] T1 INNER JOIN ON [dbo].[Table2] T2 ON T1.ID = T2.ID WHERE T1.[col1] = 'xxx' AND T2.[Col3] = 'yyy' SET NOCOUNT OFF GO
Обновить
CREATE PROC [dbo].[procTable_UPD] AS SET NOCOUNT ON UPDATE t1 SET [Column1] = @Value1 , [Column2] = @Value2 , [Column3] = @Value3 FROM [dbo].[Table1] T1 INNER JOIN ON [dbo].[Table2] T2 ON T1.[ID] = T2.[ID] WHERE T1.[col1] = 'xxx' AND T2.[Col3] = 'yyy' SET NOCOUNT OFF GO
Вставить
CREATE PROC [dbo].[procTable_INS] AS SET NOCOUNT ON INSERT INTO [Table1] ( [Column1] , [Column2] , [Column3] ) VALUES ( @Value1 , @Value2 , @Value3 ) SET NOCOUNT OFF GO
ИЛИ ЖЕ
CREATE PROC dbo.procTable_INS AS SET NOCOUNT ON INSERT INTO [table1] ( [Column1] , [Column2] , [Column3] ) SELECT [Column1] = T1.col1 , [Column2] = T1.col2 , [Column3] = T2.col3 FROM dbo.Table1 T1 INNER JOIN ON Table2 T2 ON T1.ID = T2.ID WHERE T1.[col1] = 'xxx' AND T2.[Col3] = 'yyy' SET NOCOUNT OFF GO
удалять
CREATE PROC dbo.procTable_DEL AS SET NOCOUNT ON DELETE FROM [dbo].[Table1] T1 INNER JOIN ON [dbo].[Table2] T2 ON T1.[ID] = T2.[ID] WHERE T1.[col1] = 'xxx' AND T2.[Col3] = 'yyy' SET NOCOUNT OFF GO
Если вы гуглите, существует множество стандартов кодирования. Например,
Стандарт и руководство по кодированию баз данных
а также
Полный список стандартов и руководств по кодированию базы данных SQL SERVER.
Мне лично не нравится добавлять префикс имени хранимой процедуры к sp_ - это избыточно, IMO. Вместо этого я предпочитаю ставить перед ними идентификатор "единицы функциональности". например, я вызову sprocs для обработки ордеров order_Save, order_GetById, order_GetByCustomer и т. д. Он сохраняет их все логически сгруппированными в студии управления и затрудняет выбор неправильного. (GetOrderByProduct, GetCustomerById и т. Д.)
Конечно, это личное предпочтение, другие люди могут предпочесть, чтобы все Sprocs Get были вместе, все Save и т.д.
Просто мой 2с.
Из действительно очень хорошего блога на PostgreSQL, но эта тема применима в целом:
Поддерживаемые запросы - моя точка зрения (depesz.com)
... Я решил, что мои приоритеты для написания поддерживаемых запросов:
Избегайте бесполезного набора текста.
Используйте псевдонимы для таблиц / представлений. Всегда. И сделать их разумными псевдонимами.
Отступ кода в некотором роде.
Избегайте цитат (да, именно поэтому я ненавижу Джанго)
Использовать синтаксис соединения
Я согласен с заглавными буквами зарезервированных слов и любого другого идентификатора, кроме моего собственного.
Я обычно держу очень мало на строку, то есть:
select
col1,
col2,
col3
from
some_table tabl1
where
col1 = 'some'
and
(
col2 = 'condition'
or col2 = 'other'
)
SELECT c.id
, c.name
, c.folder
, cs.num_users active_members
, cs.num_videos
FROM campaign c
JOIN campaign_stats cs
ON cs.campaign_id = c.id
JOIN (SELECT _c.id
, _c.name
FROM campaign _c
WHERE _c.type = 9) t_c
ON t_c.id = c.id
WHERE c.id IN (1,2,3)
AND cs.num_videos > 10
Это работает довольно хорошо для нас.
Этот фактический запрос не имеет особого смысла, так как я попытался построить его быстро в качестве примера... но это не главное.
- t_c обозначает подзапрос таблицы категорий или "временную категорию".
- _underscoring вещи внутри подзапросов.
- псевдоним столбцов, чтобы иметь смысл в контексте запроса. например, "active_members"
запятые в начале новых строк облегчают построение динамических запросов:
$sql .= ", c.another_column"
все остальное просто.
Все, что в голубом - это заглавные SELECT
, DELETE
, GO
, так далее
Имена таблиц единичны, как таблица, в которой хранятся наши клиенты.
Связывание таблиц tablename_to_tablename
использование _
между работами в именах таблиц и параметрах
пример
BEGIN
SELECT
Company.ID AS Company_ID,
Company.Client_Name,
Company.Website,
Office.Office_Name
FROM
Company_Office WITH(NOLOCK)
INNER JOIN Company WITH(NOLOCK) ON Company_Office.Company_ID = Company.ID
WHERE
END
Я удивлен, что стиль кодирования, который я использовал почти 20 лет, отсутствует в этом списке:
SELECT column1,
column2,
column3,
COALESCE(column4, 'foo') AS column4
FROM tablename
WHERE column1 = 'bar'
ORDER BY column1,
column2
Я нахожу это абсолютно читабельным, но признаю, что набирать его утомительно. Если выравнивание ключевых слов по правому краю слишком много, я бы выбрал выравнивание по левому краю:
SELECT column1,
column2,
column3,
COALESCE(column4, 'foo') AS column4
FROM tablename
WHERE column1 = 'bar'
ORDER BY column1,
column2
Гугл для sql симпатичный принтер или посмотри тут. Я сам не пробовал, но это дает вам хорошее начало. У большинства коммерческих инструментов, таких как Toad, есть опция "форматирования", которая тоже помогает.
Поиграйте с http://www.sqlinform.com/ - я рекомендую использовать стандарт ANSI-92, а затем довольствуйтесь этим сайтом.
Типы данных, которые будут использоваться: Мы должны использовать только следующие типы данных:
- INT
- BIGINT
- SMALLINT
- VARCHAR
- НЕМНОГО
- DATETIME
Укажите значение по умолчанию для типа данных BIT. Это не должно быть обнуляемым Имя таблицы и столбца никогда не должно быть в нижнем регистре. Это должно описать его цель. Избегайте использования коротких форм. При создании таблицы FK и PK следует хорошо продумать и определиться. Имена переменных должны начинаться с одной / двух букв, указывающих на тип данных в нижнем регистре. Например, переменная INT должна начинаться с i. Имя должно быть описательным, следует избегать кратких форм. Каждое слово должно начинаться с заглавной буквы, за которой следуют все строчные буквы.
Например
Правильный путь:- iTotalCount
Неправильный путь:- xyz
Столбцы таблицы, используемые с предложением "WHERE" внутри хранимых процедур, должны быть проиндексированы / снабжены ключами. Это увеличит скорость обработки данных. Упорядочение параметров в предложении WHERE должно выполняться правильно. Первичный ключ / индекс должен предшествовать битовым переменным. Например:- Индекс создается по комбинации столбцов (REF_ID, T_TYPE_STR, CNUMBER, TLOG_ID)
- Правильный способ, где индексированные ключи используются последовательно в предложении WHERE.
SELECT REF_ID,T_TYPE_STR,C_NUMBER,TLOG_ID
FROM T_T_DATA_tbl
WHERE REF_ID = 1
AND LOG_ID = ‘4042654’
AND T_TYPE_STR = ‘SA’
AND CNUMBER = ‘10702’
–Incorrect way
SELECT REF_ID, T_TYPE_STR, CNUMBER, LOG_ID
FROM T_T_DATA_tbl
WHERE LOG_ID = ‘4042654’
AND T_TYPE_STR = ‘SA’
При написании хранимой процедуры в начале должен быть раздел с описанием Author:
Дата создания:
Описание:
Если какой-либо sp изменяется, этот раздел должен быть добавлен с
Модифицирован:
Изменено на:
Описание:
Столбец ROW_INSERTION_DATE_TIME И ROW_UPDATION_DATE_TIME должен иметь значения по умолчанию как GETDATE().
Больше на: http://www.writeulearn.com/sql-database-coding-standards/
create table
#tempTable (
col1 int,
col2 int,
col3 int
)
insert into
#tempTable (
col1,
col2,
col3
)
select
col1,
col2,
col3
from
Table3
inner join Table2
on Table1.col1 = Table2.col2
where col1 = 5
select
col2,
case when col1 = 3
then 'something'
else 'somethingelse'
end
from #tempTable
where
col1 = 5
and (
col2 = 5
or col3 in (
select field
from Table2
where
somecol = 2
and othercol = 5
)
)