Почему не хорошо иметь первичный ключ на объединяющей таблице?

На примере @kynan в качестве основы я создал этот скрипт и поместил его в свой путь (~/bin/) как gg. Он использует git grep, но избегает некоторых указанных типов файлов.

В нашем репо много изображений, поэтому я исключил файлы изображений, и это сокращает время поиска до 1/3, если я ищу весь репо. Но скрипт может быть легко изменен, чтобы исключить другие типы файлов или geleralpatterns.

#!/bin/bash                                                                    
#                                                                              
# Wrapper of git-grep that excludes certain filetypes.                         
# NOTE: The filetypes to exclude is hardcoded for my specific needs.           
#                                                                              
# The basic setup of this script is from here:                                 
#   https://stackoverflow.com/a/14226610/42580                                  
# But there is issues with giving extra path information to the script         
# therefor I crafted the while-thing that moves path-parts to the other side   
# of the '--'.                                                                 

# Declare the filetypes to ignore here                                         
EXCLUDES="png xcf jpg jpeg pdf ps"                                             

# Rebuild the list of fileendings to a good regexp                             
EXCLUDES=`echo $EXCLUDES | sed -e 's/ /\\\|/g' -e 's/.*/\\\.\\\(\0\\\)/'`      

# Store the stuff that is moved from the arguments.                            
moved=                                                                         

# If git-grep returns this "fatal..." then move the last element of the        
# arg-list to the list of files to search.                                     
err="fatal: bad flag '--' used after filename"                                 
while [ "$err" = "fatal: bad flag '--' used after filename" ]; do              
    {                                                                          
        err=$(git grep "$@" -- `git ls-files $moved | grep -iv "$EXCLUDES"` \  
            2>&1 1>&3-)                                                        
    } 3>&1                                                                     

    # The rest of the code in this loop is here to move the last argument in   
    # the arglist to a separate list $moved. I had issues with whitespace in   
    # the search-string, so this is loosely based on:                          
    #   http://www.linuxjournal.com/content/bash-preserving-whitespace-using-set-and-eval
    x=1                                                                        
    items=                                                                     
    for i in "$@"; do                                                          
        if [ $x -lt $# ]; then                                                 
            items="$items \"$i\""                                              
        else                                                                   
            moved="$i $moved"                                                  
        fi                                                                     
        x=$(($x+1))                                                            
    done                                                                       
    eval set -- $items                                                         
done                                                                           
# Show the error if there was any                                              
echo $err                                                                      

Примечание 1

В соответствии с этим должна быть возможность назвать вещь git-gg и иметь возможность называть ее как обычный git команда вроде:

$ git gg searchstring

Но я не могу заставить это работать. Я создал скрипт в своем ~/bin/ и сделал символическую ссылку git-gg в /usr/lib/git-core/.

Примечание 2

Команду нельзя превратить в обычный sh псевдоним псевдонима, поскольку она будет вызываться в корне репо. И это не то, чего я хочу!

21
задан pez_dispenser 19 May 2009 в 01:24
поделиться

8 ответов

Некоторые примечания:

  1. Комбинация category_id и post_id уникальна сама по себе, поэтому дополнительный столбец ID является избыточным и расточительным.
  2. Фраза «нехорошо иметь первичный ключ. "неверно в скринкасте. У вас все еще есть первичный ключ - он просто состоит из двух столбцов (например, CREATE TABLE foo (cid, pid, PRIMARY KEY (cid, pid)). Людям, которые привыкли к значениям идентификаторов везде, это может показаться странно, но в теории отношений это вполне правильно и естественно; автор скринкаста лучше сказал бы, что «нехорошо иметь неявный целочисленный атрибут, называемый« ID »в качестве первичного ключа».
  3. Излишне иметь дополнительный столбец, потому что вы все равно разместите уникальный индекс для комбинации category_id и post_id, чтобы не вставлять повторяющиеся строки
  4. Наконец, хотя общепринятая номенклатура называет его «составным ключом», это также является избыточным. Термин «ключ» в реляционной теории на самом деле представляет собой набор из нуля или более атрибутов, которые однозначно идентифицируют строку, поэтому можно сказать, что первичным ключом является category_id, post_id
  5. Поместите САМЫЙ ВЫБОРНЫЙ столбец ПЕРВЫМ в первичный ключ. декларация. Обсуждение построения b (+ / *) деревьев выходит за рамки этого ответа (некоторые обсуждения более низкого уровня см .: http://www.akadia.com/services/ora_index_selectivity.html ]), но в вашем случае вы, вероятно, захотите, чтобы это было в post_id, category_id, поскольку post_id будет реже отображаться в таблице и, таким образом, сделает индекс более полезным. Конечно, поскольку таблица настолько мала, а индексом будут, по сути, строки данных, это не очень важно. Это было бы в более широких случаях, когда таблица шире.
47
ответ дан 29 November 2019 в 06:32
поделиться

Администратор баз данных скажет вам, что первичный ключ в данном случае это фактически комбинация двух столбцов FK. Поскольку Rails / ActiveRecord плохо работает с составными PK (по крайней мере, по умолчанию), это может быть причиной.

3
ответ дан 29 November 2019 в 06:32
поделиться

Комбинация внешних ключей может быть первичным ключом (называемым составным первичным ключом). Лично я предпочитаю использовать технический первичный ключ вместо этого (поле автоматического номера, последовательность и т. Д.). Зачем? Что ж, это упрощает идентификацию записи, что вам может потребоваться, если вы собираетесь ее удалить.

Подумайте об этом: если вы собираетесь представить веб-страницу с все связи,

3
ответ дан 29 November 2019 в 06:32
поделиться

Плохая идея - не иметь первичного ключа в какой-либо таблице, точка (если СУБД является реляционной СУБД или СУБД SQL). Первичные ключи - важная часть целостности вашей базы данных.

Я полагаю, если вы не возражаете против того, чтобы ваша база данных была неточной и время от времени давала неверные ответы, тогда вы могли бы обойтись без ... но большинство людей хотят точных ответов от их СУБД и для таких людей первичные ключи имеют решающее значение.

3
ответ дан 29 November 2019 в 06:32
поделиться

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

Но это просто говорит о том, почему это не хорошая идея ... но почему это может быть плохая идея?

Подумайте о накладных расходах, добавляемых при добавлении столбца идентификации. Таблица займет на 50% больше дискового пространства. Хуже обстоит дело с индексом. С полем идентификатора вы должны поддерживать счетчик идентификаторов плюс второй индекс. Вы утроите дисковое пространство и утроите объем работы, который необходимо выполнять с каждой вставкой. Единственное преимущество - это немного более короткое предложение WHERE в команде DELETE.

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

3
ответ дан 29 November 2019 в 06:32
поделиться

Размещение самого селективного столбца первым должно быть актуально только в объявлении INDEX. В объявлении KEY это не должно иметь значения (потому что, как было правильно указано, KEY - это SET, а внутри набора порядок не имеет значения - набор {a1, a2} совпадает с набором {a2 , a1}).

Если продукт СУБД таков, что упорядочение атрибутов внутри объявления KEY имеет значение, то этот продукт СУБД виновен в том, что не различает должным образом логическую структуру базы данных (часть, в которой вы выполняете KEY) и физический дизайн базы данных (часть, где вы делаете объявление INDEX).

2
ответ дан 29 November 2019 в 06:32
поделиться

Плюсы наличия одного ПК

  • Однозначно идентифицирует строку с одним значением
  • Облегчает ссылку на связь из другого места, если это необходимо
  • Некоторые инструменты хотят, чтобы у вас было одно целое значение pk

Недостатки использования одного PK

  • Использует больше дискового пространства
  • Требуется 3 индекса, а не 1
  • Без уникального ограничения вы можете получить несколько строк для того же отношения

Примечания

  • Вам нужно определить уникальное ограничение, если вы хотите избежать дублирования
  • На мой взгляд, не используйте один pk, если ваша таблица будет огромной, иначе торгуйте отключите место на диске для удобства. Да, это расточительно, но кого волнуют несколько мегабайт на диске в реальных приложениях.
1
ответ дан 29 November 2019 в 06:32
поделиться

Я хотел прокомментировать следующий комментарий: «Неправильно скажите ноль или более ».

Я хотел отметить, что текст, к которому был добавлен этот комментарий, просто не содержал текста« ноль или более », поэтому автор комментария, который я хотел прокомментировать, критиковал кого-то еще за кое-что, чего не было сказано.

Я также хотел прокомментировать, что неправильно говорить «ноль или больше». Теория отношений, широко известная сегодня среди тех немногих, кто все еще пытается изучить детали этой теории, на самом деле ТРЕБУЕТ возможности ключа без атрибутов.

2
ответ дан 29 November 2019 в 06:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: