Форум: "Прочее";
Текущий архив: 2013.04.28;
Скачать: [xml.tar.bz2];
ВнизНазвание поля первичного ключа. Найти похожие ветки
← →
Дмитрий С © (2012-12-23 14:07) [0]Предположим таблица новостей `new`.
Как лучше назвать поле PK:
id или new_id ?
← →
Медвежонок Пятачок © (2012-12-23 14:14) [1]create table dat_news(
dn_id number not null, primary key,
...
);
← →
Юрий Зотов © (2012-12-23 14:31) [2]ИмяПоля - поле таблицы.
ИмяТаблицы_ИмяПоля - внешняя ссылка на это поле.
← →
Юрий Зотов © (2012-12-23 14:42) [3]Эта система наименований полей удобна тем, что по имени поля таблицы сразу ясно, куда оно ссылается, или не ссылается никуда.
← →
Дмитрий С © (2012-12-23 16:34) [4]
> create table dat_news(
> dn_id number not null, primary key,
> ...
> );
Во-первых можно получить одинаковые аббревиатуры, во-вторых получаем еще одно лишнее имя.
> ИмяПоля - поле таблицы.
> ИмяТаблицы_ИмяПоля - внешняя ссылка на это поле.
>
>
это получается
id в таблице new
и new_id в ссылающихся таблицах?
У меня так и сделано, но смущает, что у MySQL есть упрощенный синтаксис join-а:
FROM new JOIN <table> USING (new_id)
Но в обеих таблицах должно быть поле new_id . Не спроста же есть такой синтаксис.
← →
Медвежонок Пятачок © (2012-12-23 17:02) [5]Во-первых можно получить одинаковые аббревиатуры, во-вторых получаем еще одно лишнее имя.
Можно и получить. Если стараться.
Я не получаю.
Лишних имен у меня нет.
← →
Игорь Шевченко © (2012-12-23 17:35) [6]
> Предположим таблица новостей `new`.
плохое предположение, таблица новостей должна иметь имя news.
и да, имена полей в таблице не должны дублировать ее имя.
> Не спроста же есть такой синтаксис.
у MySQL все не так, как у людей
← →
Аббат Пиккола (2012-12-24 12:21) [7]Как лучше назвать поле PK:
id или new_id ?
Я сотни раз делал и так и так.
Могу сказать, что есть некоторое преимущество у того чтобы назвать new_id но с одной оговоркой. Все ссылки из других таблиц на это порле также должны называться new_id, а не имя_другой_табицы_new_id
Для целей автоматической нормализации case-средства часто используют подход, сводящийся к тому, чтобы поле называлось таблица_поле и все внешние ссылки на него тоже назывались таблица_поле.
Например
user_id
user_name
article_id
article_name
user_id это - id автора статьи. то есть ссылка на PK таблицы user
Дело в том, что user_id это совершенно определенное понятие и ВО ВСЕХ таблицах оно будет означать одно и то же - id пользователя. И во всех таблицах одинаково называться.
Неверно говорить "лучше называть имя таблиы_имя поля".
верно говорить "лучше называть имя_сущности_имя_атрибута".
Тогда все встанет на свои места.
Если имеется такая сущность:
user_id
user_name
article_id
article_name
То при автоматической нормализации CASE-средство выделит сущность acrticle в отдельную таблицу и организует внешний ключ на таблицу user_id после того как получит ответ на вопрос как соотносятся сущности user и article (ответ один user ко многим article).
← →
Ega23 © (2012-12-24 12:31) [8]Делал тремя различными способами.
Разницы никакой, главное, чтобы остальные члены команды понимали.
← →
Аббат Пиккола (2012-12-24 12:48) [9]Абстрагируемся от того, хорошо ли название NEW для таблицы. Или лучше NEWS. На английском новость (одна) - тоже NEWS.
Но во всех остальных случаях я лично предпочитаю называть сущность в единственном числе, а не во множественном (BOOK - таблица, в которой лежат книги). Допустим у меня имеется таблица с книгами и таблица с авторами и таблица издателей.
BOOK
------------
BOOK_ID
BOOK_NAME
BOOK_YEAR
AUTHOR_ID
PUBLISHER_ID
AUTHOR
-----------
AUTHOR_ID
AUTHOR_NAME
PUBLISHER
-------------
PUBLISHER_ID
PUBLISHER_NAME
Это - самый строгий вариант.
Но возможен и упрощенный вариант, если я не собираюсь использовать какие-либо средства автоматической нормализации и хочу максимума лаконичности:
BOOK
------------
ID
NAME
AYEAR
AUTHOR_ID
PUBLISHER_ID
AUTHOR
-----------
ID
NAME
PUBLISHER
-------------
ID
NAME
При таком (лаконичном) подходе я именую сами констрейнты:
PK_BOOK_ID
PK_AUTHOR_ID
PK_PBLISHER_ID
FK_BOOK_AUTHOR_ID
FK_BOOK_PUBLISHER_ID
И получается все максимально лаконично и все названия констрейнтов получаются заведомо уникальными.
Но за много лет я так и не выбрал для себя какой-то из этих двух стилей как единственно верный. Хотя склоняюсь ко второму (хотя и реже им пользуюсь). В нем сразу заметны атрибуты иных сущностей в таблице. А в "лаконичном" - не сразу заметны. Так как в строгом варианте всякий атрибут, не начинающейся с имени сущности (префикса) выдает себя "я чужой", а в лаконичом варианте нужно обращать внимание на суффикс _ID, что требует больше внимания, так как префиксы видны лучше, чем суффиксы и сазу бросаются в глаза.
← →
Аббат Пиккола (2012-12-24 13:00) [10]Ega23 © (24.12.12 12:31) [8]
Согласен.
Могу предложить еще один подход, сочетающий лаконичность и строгость.
Только ключевые поля (как первичные, так и внешние) содержат префикс "сущность". Все остальные поля называем лаконично.
Тогда все выглядит так:
AUTHOR
--------
author_id
name
PUBLISHER
----------
publisher_id
name
BOOK
----------
book_id
name
ayear
author_id
publisher_id
← →
wl © (2012-12-24 13:01) [11]есть же ветка "Базы", зачем это в прочем то помещать?
← →
Jeer © (2012-12-24 13:03) [12]TableName_FieldName
Пришел к такому варианту давно, перепробовав и ручные и case-подходы.
Избегать использования ключевых слов в именах таблиц и полей следует всегда.
← →
Toha_Nik (2012-12-24 13:08) [13]
> Ega23 © (24.12.12 12:31) [8]
точно, главное что PK и FK
← →
знайка (2012-12-24 13:18) [14]UserId, NewsId...
← →
MsGuns © (2012-12-24 13:20) [15]ИМХО, самое простая и понятная система:
1) RN/ID - собственно идентификатор, PRN/PID - ссылки на узлы (главные записи - FK), FRN/FID - ссылки на словари (ссылочные записи - FK)
2) При составлении запросов перед именем поля ВСЕГДА ставится имя таблицы/алиас
3) При создании таблицы (скрипт CREATE) ОБЯЗАТЕЛЬНО присутствует сотв. комментарий
4) Как альтернативный вариант - замена доступных клиенту селектов вьюхами, где имена возвращаемых колонок не зависят от физ.таблиц, которые делаются недоступными пользователю НЕПОСРЕДСТВЕННО.
Использование имен ссылочных таблиц в именах полей приводит к загромождению скл-запросов лишними "букавами", что делает их чтение весьма затруднительным
← →
Дмитрий С © (2012-12-24 13:20) [16]А как быть с двойными ссылками?
Допустим таблица тем форума: thread, у нее помимо прочих два поля: "автор темы", "автор последнего сообщения". Оба поля не назовешь же user_id. Как тут быть?
← →
Медвежонок Пятачок © (2012-12-24 13:22) [17]Как тут быть?
неужели придется дать разные имена?
← →
Аббат Пиккола (2012-12-24 13:35) [18]Аргумент в пользу того, чтобы назвать поле AUTHOR_ID как в таблице AUTHOR, так и в таблице BOOK, если мы используем Delphi для работы с таблицами.
Допустим я использую каких-то наследников от TDataSet и организую два редактируемых результата запроса на форме в отношении главный-подчиненный
Query1
SELECT AUTHOR_ID, NAME FROM AUTHOR
Query2
SELECT BOOK_ID, NAME, AUTHOR_ID FROM BOOK
WHERE AUTHOR_ID = :AUTHOR_ID
и DataSource1
И такие еще связи между компонентами
DataSource1.DataSet := Query1;
Query2.DataSource := DataSource1;
При таком подходе удобнее иметь сразу поле AUTHOR_ID, а не неопределенное ID. Так как манера называть поля ID без префикса приведет к такому запросу:
Query2
SELECT ID, NAME, AUTHOR_ID FROM BOOK
WHERE AUTHOR_ID = :ID
Или же в первом запросе придется заюзать алиас AUTHOR_ID для поля ID, чтобы избежать проблем. Так не лучше ли с самого начала иметь такое название для поля?
← →
Аббат Пиккола (2012-12-24 13:37) [19]2 Дмитрий С © (24.12.12 13:20) [16]
А как быть с двойными ссылками?
Хороший вопрос
← →
Ega23 © (2012-12-24 13:39) [20]Лично сейчас остановился на id для PK, Имя_Сущности + id для FK.
Т.е.create table master (
id...,
.....,
constraint pk_master primary key (id)
)
create table detail (
id,
masterid,
lastmasterid,
.....
constraint pk_detail ... (id)
constraint fk_detail_ref_master
constraint fk_detail_refmaster_2
)
Поиск вторичного ключа по имени - честное слово, я не припомню, чтобы такая задача в практике возникала. А так - всегда можно посмотреть, кто там на что ссылается. Поэтому последующие ключи таблицы Detail на таблицу Master - смело нумеровать, как 2, 3, ... N
← →
Ega23 © (2012-12-24 13:41) [21]
> При таком подходе удобнее иметь сразу поле AUTHOR_ID, а
> не неопределенное ID. Так как манера называть поля ID без
> префикса приведет к такому запросу:
При таком подходе тебе никто не мешает сделать select id as authorid from authors
Или ваще использовать вьюхи.
← →
Аббат Пиккола (2012-12-24 13:41) [22]Эти случаи составляют редкость, пожэтому я обычно как-то выкручиваюсь. То есть отклоняюсь от общей системы наименований. Вместо user_id использую theme_author_id, last_message_author_id. Если это РЕДКОСТЬ, то можно поозволить себе ИСКЛЮЧЕНИЕ. Если же таких вещей уйма, ито буду искать какое-то подходящее решение, возможно отклонюсь от своих обычных привычек.
← →
Аббат Пиккола (2012-12-24 13:43) [23]2 Ega23 © (24.12.12 13:41) [21]
Я так и поступаю. Я склоняюсь в полной лаконичности (использую ID), Но всякий раз приходится применять алиасы, поэтому часто сожалею, что не использовал префикс. В общем колебания у меня остаются, хотя привычка не использовать префиксы слишком сильна.
← →
Аббат Пиккола (2012-12-24 13:48) [24]Обсуждение показывает, что нет какого-то одного единственно правильного решения. Более того, одни и те же люди используют то один подход, то другой.
← →
MsGuns © (2012-12-24 13:57) [25]Вот пример далеко не самого большого запроса, оформленного "по правилам".
Разбирать его - все равно что искать монетки в куче навоза :)
const AnsiString SQL_ORACLE_SELECT_ASTRA_REESTR_OUT1 = \
"SELECT temp_nalog.obor_date, \
temp_nalog.cez_id, \
CASE WHEN temp_nalog.cez_id IS NULL THEN 1 ELSE 0 END ntk_id, \
temp_nalog.provider_id, \
temp_nalog.provider_taxdoc, \
temp_nalog.provider_taxnum, \
temp_nalog.provider_name, \
temp_nalog.personal_count, \
temp_nalog.abonstatus_id, \
temp_nalog.abon_name, \
DECODE(nvl(temp_nalog.taxpayer_type, 1), 1, \
decode(trim(temp_nalog.tax_num), "не платник", "0", trim(temp_nalog.tax_doc)), \
"0") tax_doc, \
DECODE(nvl(temp_nalog.taxpayer_type, 1), 1, \
decode(trim(temp_nalog.tax_num), "не платник", "0", trim(temp_nalog.tax_num)), \
"0") tax_num, \
temp_nalog.nalog_num, \
temp_nalog.nalog_series, \
temp_nalog.nalog_date, \
temp_nalog.nalog_num_old, \
temp_nalog.nalog_series_old, \
temp_nalog.nalog_date_old, \
temp_nalog.obor_date_calc, \
temp_nalog.formtype_id, \
nvl(temp_nalog.taxpayer_type, 1) taxpayer_type, \
temp_nalog.is_correction, \
temp_nalog.status, \
temp_nalog.codification_code, \
"0" || decode(temp_nalog.ndstype_id, 4, 2, temp_nalog.is_correction) || decode(temp_nalog.ndstype_id * temp_nalog.is_correction, 4, 2, abs(temp_nalog.status)) nalog_type, \
case when trim(temp_nalog.tax_num) = :tn \
then "ЗЦ" \
when temp_nalog.ndstype_id = 4 \
then "БО" \
when temp_nalog.is_correction = 1 \
then "РК" \
else "ПН" \
end || \
case when temp_nalog.ndstype_id = 4 \
then "" \
when temp_nalog.formtype_id = 2 \
then "11" \
when DECODE(nvl(temp_nalog.taxpayer_type, 1), 1, \
decode(trim(temp_nalog.tax_num), "не платник", "0", trim(temp_nalog.tax_num)), "0") = "0" \
then "02" \
else "" \
end || \
case when temp_nalog.status <> 1 \
then "У" \
else "" \
end document_type, \
max(case when is_correction = 0 \
then "" \
when trim(temp_nalog.correct_reason) in ("01","03") \
then trim(temp_nalog.correct_reason) \
else "02" \
end) correct_reason, \
sum(temp_nalog.summa - temp_nalog.summa_pension) summa_all, \
sum(temp_nalog.summa_pension) summa_pension, \
sum(temp_nalog.summa_avans) summa_avans_all, \
RoundTax(sum((temp_nalog.summa - temp_nalog.summa_pension) * temp_nalog.nalog_percent / (100 + temp_nalog.nalog_percent)), 2) summa_nds, \
sum(case when temp_nalog.nalog_percent = 0 \
then temp_nalog.summa - temp_nalog.summa_pension \
else 0 \
end) summa_notnds, \
max((select max(nds_percent.percent) keep (dense_rank last order by nds_percent.setup_date) \
from nds_percent \
where nds_percent.setup_date <= temp_nalog.obor_date)) nalog_percent \
FROM (select i.obor_date, \
temp_nalog.oborinfo_id, \
temp_nalog.cez_id, \
temp_nalog.provider_id, \
temp_nalog.provider_taxdoc, \
temp_nalog.provider_taxnum, \
temp_nalog.provider_name, \
temp_nalog.personal_count, \
temp_nalog.abonstatus_id, \
temp_nalog.abon_name, \
temp_nalog.tax_doc, \
temp_nalog.tax_num, \
temp_nalog.nalog_percent, \
nvl(temp_nalog.pension_percent,0) pension_percent, \
temp_nalog.nalog_num, \
DECODE(temp_nalog.status, 3, SUBSTR(temp_nalog.nalog_series, 2), temp_nalog.nalog_series) nalog_series, \
temp_nalog.nalog_date, \
temp_nalog.nalog_num_old, \
temp_nalog.nalog_series_old, \
temp_nalog.nalog_date_old, \
min(decode(temp_nalog.pension_percent, 100, 99999999, temp_nalog.service_id)) service_id, \
temp_nalog.obor_date_calc, \
temp_nalog.ndstype_id, \
temp_nalog.formtype_id, \
temp_nalog.taxpayer_type, \
temp_nalog.is_correction, \
temp_nalog.correct_reason, \
temp_nalog.codification_code, \
temp_nalog.status, \
sum(temp_nalog.volume) volume, \
sum(temp_nalog.summa) summa, \
sum(temp_nalog.summa_avans) summa_avans, \
case when nvl(temp_nalog.pension_percent,0) = 0 \
then 0 \
when temp_nalog.pension_percent = 100 \
then sum(temp_nalog.summa) \
else RoundTax(sum(temp_nalog.summa) * temp_nalog.pension_percent \
/ (100 + temp_nalog.nalog_percent + temp_nalog.pension_percent), 2) \
end summa_pension \
FROM &&&.obor_nalog temp_nalog, &&&.obor_info i \
WHERE temp_nalog.oborinfo_id = i.oborinfo_id ";
← →
Ega23 © (2012-12-24 14:14) [26]
> Вот пример далеко не самого большого запроса, оформленного
> "по правилам".
Вот такое я бы точно в виде view оформлял.
← →
Ega23 © (2012-12-24 14:17) [27]
> Обсуждение показывает, что нет какого-то одного единственно
> правильного решения. Более того, одни и те же люди используют
> то один подход, то другой.
Дело не в этом. Просто в одной компании, где я работал, было принято префикс и для вторичного, и для первичного писать.
Где сейчас работаю - префикс для первичного писать не принято.
Лично мне "переключиться" - дело пятнадцати минут.
практика показывает, что не надо применять названия Table1, Column2, Domain3 и StoredProc4, так точно запутаешься.
← →
Аббат Пиккола (2012-12-24 14:18) [28]Боюсь, что если его "не по правилам" оформить, то от этого он лучше не станет.
← →
vuk © (2012-12-24 14:53) [29]У нас делается так - для каждой таблицы выбирается префикс и все поля имеют вид Префикс_Имя. В связанных таблицах поля имеют те же имена, что и в основной.
Типа того:
GoodsTypes
-----------
gt_id int
gt_Name varchar
gt_DisplayOrder
...
Goods
-----------
g_id int
gt_id int
g_Name varchar
...
← →
Jeer © (2012-12-24 15:00) [30]Ну да, это не суть как именовать префикс - табличным именем или алиасом.
Во втором случае можно сделать короче, но нужна таблица перевода :)
← →
Аббат Пиккола (2012-12-24 15:01) [31]Жаль, что нет ресурса, на котором все бы выложили свои стили.
А разработчик нового проекта мог бы ознакомиться с ними и выбрать что-то наиболее подходящее.
Например, подход vuk © (24.12.12 14:53) [29] обладает строгостью и одновременно достаточно лаконичен.
← →
Аббат Пиккола (2012-12-24 15:03) [32]Инетересно. Ведь эти же алиасы затем можно использовать и при написании SQL-запросов как алиасы для самих таблиц.
← →
vuk © (2012-12-24 15:07) [33]to Jeer © (24.12.12 15:00) [30]:
> Во втором случае можно сделать короче, но нужна таблица
> перевода :)
Для частоиспользуемых таблица перевода уже на подкорке. Для редкоиспользуемых достаточно посмотерть наименование полей в таблице. :)
Да, кстати, эти же префиксы, как правило, используются для псевдонимов в join-ах.
Единственный минус - префиксы иногда выходят зубодробительные. :)))
← →
Ega23 © (2012-12-24 15:25) [34]
> Жаль, что нет ресурса, на котором все бы выложили свои стили.
>
> А разработчик нового проекта мог бы ознакомиться с ними
> и выбрать что-то наиболее подходящее.
> Например, подход vuk © (24.12.12 14:53) [29] обладает
> строгостью и одновременно достаточно лаконичен.
Я, к сожалению, не могу найти документа сейчас. Но он был, где-то на 4 странички, "Соглашения о наименованиях".
Там всё чётко было расписано, как формируется название столбца, какие символы не могут присутствовать, какие типы данных для чего используются и т.д.
В целом - как vuk привёл, очень похоже.
← →
Toha_Nik (2012-12-24 15:33) [35]Ну да, там где автоматом, как для часто используемых - порядок какой-то помогает, а где редко - все равно по связям смотришь..., а посмотрел, уже и не особо важно как названо(в памяти то не держишь).
← →
Компромисс1 (2012-12-24 15:51) [36]MsGuns © (24.12.12 13:57) [25]
Странно, что не введен алиас для temp_nalog, хотя введен алиас для obor_info
← →
vuk © (2012-12-24 15:54) [37]to Toha_Nik (24.12.12 15:33) [35]:
> а посмотрел, уже и не особо важно как названо(в памяти то
> не держишь).
Как названо, все равно важно. Использование уникальных префиксов еще позволяет обходиться без переименования полей в сложных запросах, в рамках БД просто не будет полей с одинаковым названием, но имеющих разный смысл.
← →
Ega23 © (2012-12-24 16:00) [38]Вот, коллега прислал, тот самый документ.
Публикую выдержки, полностью - не могу, спасибо за понимание
1.2 Общие положения
1.2.1 Имена в БД должны максимально описывать соответствующие сущности.
1.2.2 Имена должны максимально соответствовать грамматике английского языка.
1.2.3 Имена не должны быть слишком длинными, но применяемые в них сокращения должны быть понятны и благозвучны.
1.2.4 В качестве имен не допускается применение слов, которые могут оказаться резервированными в используемых программных средах (например, слов ORDER, SELECT, DENY, etc)
1.2.5 Рекомендуемые регистры наименований – первые буквы заглавные, остальные – прописные, либо начальные буквы составляющих слов заглавные, остальные – прописные (CamelCaps). Использование подчеркиваний и прочих знаков не допускается.
1.3 Таблицы
1.3.1 Рекомендованная длина имен таблиц – не более 12 символов
1.3.2 Рабочие таблицы – списки именуются именем или его сокращением во множественном числе. Возможно составное имя.
Например, Persons, Classes, ClassGroups, ClsGroups, ClsStates, Clstypes
1.4.2 Суффиксы.
Универсальные имена в случае необходимости могут быть дополнены суффиксами, а также нумераторами (0,1,..). Использование в одном имени и суффиксов, и нумераторов не рекомендуется.
<Имя>= <Универсальное имя><Суффикс>|<нумератор>
Рекомендованные суффиксы:
In – начальный, исходный (например, для дат)
Out – конечный, выходной (например, для дат)
Add – дополнительная или альтернативная информация
Min – минимальное значение, тип данных int, numeric
Max – максимальное значение, тип данных int, numeric
Примеры:
DateIn, DateOut, ValMin, ValMax, NrAdd, Nr1, Nr2.
Примечание. При использование суффиксов однородные семантически поля будут стоять рядом в алфавитно-упорядоченном списке.
1.5 Хранимые процедуры
1.5.1 Имена хранимых процедур
Имя хранимой процедуры составляется из префикса S_, описателя (наименования или аббревиатуры) обрабатываемой сущности, уточненного описателя сущности, и конкретного описателя действия, или общего описателя действия – слова «рroc»:
<имя процедуры>=S_<описание сущности>[<уточненное описание>][<описание действия>|proc]
Например,
S_PersEdit, S_PersSearch, S_CarsProps, S_CarsProc, S_DOTCheck, S_DOTSync
Рекомендованная длина имен процедур – не более 12 символов
1.5.2 Файлы хранимых процедур
Файлы хранимых процедур должны называться по имени процедур.
Примечание. Не рекомендуется включать несколько процедур в один файл. Хотя был опыт хранения в одном файле s_misc 15 сервисных процедур и функций общего назначения, практически, не менявшихся длительное время. При прогоне утилитой командной строки этот файл исполнялся в рамках одного соединения, что экономило время 14 коннектов.
Ну и т.д.
← →
Kerk © (2012-12-24 16:01) [39]Меня иногда пугает глобальность и важность вопросов, поднимаемых и - главное - на полном серьезе обсуждаемых на этом форуме :)
← →
Игорь Шевченко © (2012-12-24 16:20) [40]Joe Celko давно все рассказал, как и что называть
http://books.google.ru/books/about/Joe_Celko_s_SQL_Programming_Style.html?id=90c41yKz3IUC&redir_esc=y
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2013.04.28;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.01 c