Things every developer absolutely, positively needs to know about database indexing – Kai Sassnowski

SOME Difference Between B-tree and Binary tree

https://www.tutorialspoint.com/difference-between-b-tree-and-binary-tree

Първа разлика: При B-Tree родителският елемент може да има N на брой наследника, а не само 2 като при Binary tree.

Втора разлика: При B-Tree всички последни елементи (листата) са винаги на едно ниво, за разлика от Binary tree. И по този начин при B-Tree за да намерим дадено „листо“ и тръгнем от root елементът, ще ни трябват винаги еднакъв брой стъпки.
И всички „листа“ при B-Tree са сортирани.
И има връзка (т.н. double linked list) между отделните „групички“ (т.н. sets of leafnodes) листа на отделните „родители“, за да не се налага да се връщаме едно ниво нагоре когато търсим, която я няма в даденият set of leafnodes.

Сурогатен ключ

Tова е ключ, който е изкуствено добавен, за да служи като най-често Първичен ключ. Тоест, на които самата RDBMS им задава стойността автоматично, например AUTO_INCREMENT или различни GUID стойности (като при MSSQL), sequences в PostgreSQL…

Всеки със сигурност е използвал Сурогатен ключ и то не веднъж. Всеки път като създадеш ново поле, което служи за ID и е целочислен, положителен AUTO_INCREMENT, и го зададем за Първичен ключ, това е на практика Сурогатен ключ.

Идеята е да служат за изцяло служебна цел и по принцип нямат стойност извън Базата Данни, и не носят никаква информация чисто за приложението, което използва дадената таблица.

Има голямо застъпване на понятията Първичен и Сурогатен ключ. Първичният ключ е вид Сурогатен ключ.

Потенциален ключ

Представяме си един UNIQUE ключ. Ако махнем едно поле и уникалността се запази – това е Супер ключ. Ако се счупи – това е Потенциален ключ.

Супер ключ е нещо като лошо дефиниран UNIQUE ключ, тоест – има излишни атрибути, които и да махнем от този UNIQUE ключ, няма да счупим начинът, по който можем уникално да определим даденият запис.

Разликата между Супер ключ и Потенциален ключ е, че единият удовлетворява само изискването за уникалност, другият – и за минималност.

Потенциално, всеки от Потенциалните ключове може да е Първичен ключ, принципна разлика между двете няма.

Просто си задай въпроса: „Кое поле, или минимална комбинация от полета, може да ми гарантира уникалността на реда“, и това е.

Eто пример, това са възможните Супер ключове:
{p_id}
{p_id, p_firstname}
{p_id, p_surname}
{p_id, p_firstname, p_surname}

Koй е Потенциалният ключ?
{p_id} защото отговаря и на изискването за уникалност, и за минималност.

Prime attribute са тези полета, които са част от някои от Потенциалните ключове.

Съответно, Non-prime attributes са такива, които дори и да са част от някой от Супер ключовете, не са част от никой от Потенциалните ключове.

Литература:

https://en.wikipedia.org/wiki/Candidate_key

Composite key and Compound key

Composite key е такъв ключ, който е съставен от повече от едно поле.

Compound key е такъв ключ, чиито отделни полета са от своя страна Foreign keys към други таблици.

Типичен пример за Compound key имаме в т.н. junction tables, където обединяваме други 2 таблици например, и имаме Потенциален ключ от две полета, всяко от което „гледа“ към своята си таблица.

Литература:

https://en.wikipedia.org/wiki/Composite_key

Alternative key

За Алтернативен ключ се смята Потенциален ключ, който не се използва на практика за поддържане на уникалността. Образни казано – Потенциален ключ, който си е останал потенциален, но за него може и да има, може и да няма дефиниран например UNIQUE ключ, това не е от значение, просто идеята е, че като определим всички Потенциални ключове и „короноваме“ един от тях за Първичен, останалите ще наричаме Алтернативни ключове.

Добър пример би бил – аристокрацията на една държава, трябва да короноваме крал – един от аристократите. Останалите остават Алтернативни ключове – такива, които могат да бъдат крале, но не са.

If a table has more than one candidate key, one of them will become the primary key and rest of all are called alternate keys.

Литература:

https://www.javatpoint.com/alternate-key-in-sql

Index selectivity

Селективността на даден индекс е понятие, близко свързано с неговата кардиналност. В смисъл такъв, че селективността е по-скоро коефициент, равен на отношението между кардиналността на даденият индекс, към кардиналността на таблицата.

Selectivity = Index cardinality / Table cardinality

Колкото селективността е по-близо до 1, толкова по-добре, толкова повече търсенето по даденият индекс ще е по-конкретно и недвусмислено.

Index selectivity is how tightly a database index helps narrow the search for specific values in a table.

Понятия, като index cardinality и index selectivity не са просто суха статистика, защото query planner-ът ги използва за да прецени предварително колко резултата биха съвпаднали с търсеното. RDBMS системата винаги трябва да има нещо като „хистограма“ или мета информация за самата информация, която управляваната от нея БД съдържа.

Литертатура:

https://orangematter.solarwinds.com/2018/07/18/what-is-database-index-selectivity/

Как се определят всички възможни Супер ключове в дадена таблица

A superkey is a set of one or more attributes that, taken collectively, allow us to
identify uniquely a tuple in the relation. For example, the ID attribute of the relation
instructor is sufficient to distinguish one instructor tuple from another.

  1. Написваш всички възможни комбинации от колони – по единично, по двойки, по-тройки и т.н…
  2. Трябва и едни празен вариaнт да има – {}
  3. Oт тези варианти, махаш всички, които имат повтярящи се стойности.
  4. Тези, които остават са Супер ключовете.

Например:

Monarch NameMonarch NumberRoyal House
EdwardIIPlantagenet
EdwardIIIPlantagenet
RichardIIIPlantagenet
HenryIVLancaster

{}
{Monarch Name}
{Monarch Number}
{Royal House}
{Monarch Name, Monarch Number}
{Monarch Name, Royal House}
{Monarch Number, Royal House}
{Monarch Name, Monarch Number, Royal House}

Виждаме обаче, че за {Monarch Name, Royal House} се получават повтарящи се кортежи – Edward, Plantagenet – следователно, махаме комбинацията {Monarch Name, Royal House}, тя не може да бъде Суперключ.

За {Monarch Number, Royal House} също може да се получат повтарящи се кортежи, за конкретният случай – не, затова може да е Суперключ, но в перспектива – не.

Тази комбинация {Monarch Name, Monarch Number} може да е Суперключ, защото няма как да има два краля с еднакво име и номер едновремено.

Така, получихме тези две комбинации, които могат да са Суперключ:
{Monarch Name, Monarch Number}
{Monarch Name, Monarch Number, Royal House}

Но в същото време, само първата е напълно достатъчна за да гарантира уникалността на кортежите. Това е вече Candidate Key (Потенциален ключ).

Следователно, в релация с n атрибута, максималният брой възможни Суперключа са 2^n

На практика Суперключовете нямат голямо значение, те са по-скоро за улесняване на DB дизайна – да преценим от кои полета имаме нужда за да карантираме уникалността на всеки запис. И ако например, няма такова/такива полета – да добавим ново поле, което да свърши тази работа.

След това, на тази база, да изберем и Потенциалният ключ, който да е всъщност минималният Суперключ. Защо се казва „потенциален“? Защото, подобно на Суперключа, можем да имаме повече от един, и просто трябва да изберем един.

Много е важно, при DB design да се разсъждава в перспектива – например, с оглед на това, какво би нарушило уникалността на записите. Затова Суперключове и Потенциални ключове трябва да се избират не само на база вече съществуваща таблица, а и в перспектива.

Литература:

https://en.wikipedia.org/wiki/Superkey

Key vs. Index

Първо, първичните ключове имат за цел да гарантират уникалността на реда, уникалните ключове – на полето. Не че уникалните също не могат да гарантират уникалността на реда, но трябва да са NOT NULL.

Кое е подмножество на кое?

Ключовете са за гарантиране на уникалността на стойностите в поле или на целия ред. Индексите – само за повишаване бързодействието на SELECT заявките, или за други функционалности като FULLTEXT търсене например.

Ключовете прилагат т.н. Integrity Constraints, индексите – не.

Kлючовете не трябва да се променят без да се внимава, защото може да са FOREIGN KEYs. Индексите – могат свободно.

Index cardinality

Първо, да не се бърка с table cardinality, което значи „броят записи избщо в таблицата“.

Index cardinality refers to the uniqueness of values stored in a specified column within an index.

Явно затова кардиналността на UNIQUE индексите е равна на броя редове, върху които е даденият UNIQUE индекс, просто всички са уникални.

Aми ако има NULL стойности? Те как се броят за кардиналността? Групират се и се броят като уникални, като отделни, уникални стойности?
Тоест ако имаме 20 уникални not null стойности и отделно още примерно 3 NULL-а, (следователно – 23 реда в таблицата), кардиналността ще е 23!

Тоест, броя уникални + броя NULL стойности.

Колкото кардиналността на индекса е по-малка от броя редове на таблицата (table cardinality), толкова по-малко са уникалните стойности на това поле.

A unique index would have cardinality equal to the number of rows in the table.  But a non-unique index can have a cardinality of anywhere from 1 to the number of rows in the table, depending on how many times each index key appears in the table.

Каква е принципната полза от кардиналността?

Една полза би била за да се подобри т.н. „selectivity“ на даденото поле/полета. Колкото по-голяма е кардиналността (тоест броя уникални стойности на базата на общият брой стойности), това значи, че дадената SELECT заявка ще използва даеният индекс по-оптимално, за намиране на търсеният резултат, с по-малко търсене.

Селективността може лесно да се намери като разделим броя уникални стойности на общият брой стойности. Идеалната селективност е 1. Демек, идеалният индекс е този който не съдържа повтарящи се стойности.

Колкото селективността е по-близо до 1, толкова повече има смисъл от индекс за това поле/полета. Както и обратното – колкото по-малко на брой уникални стойности имаме, в отношение с целият брой стойности – толкова повече индексът би бил безсмислен.

Колкото селективността на един индекс е по-близо до 1, толкова и ползата му е по-голяма. Поне за B-tree индексите. За да си го представим по-нагледно, спомнете си за онази игра, дето пускаш едно топче по едни възли и на всеки възел може да отиде или на ляво, или на дясно…

Литература:

https://www.ibm.com/developerworks/data/library/techarticle/dm-1309cardinal/index.html

https://orangematter.solarwinds.com/2020/01/05/what-is-cardinality-in-a-database/

Integrity Constraints

Под Integrity Constraints се има предвид набор от правила, които съхраняваната в дадена БД информация трябва да спазва, за да се запазва качеството на информацията. Под „качество на информацията“ нека имаме предвид нейната полезност според случая, според нуждите, за които тя се използва. В този смисъл, може да се каже, че Integrity Constraints отговарят и поддържат семантичната стойност на информацията.

Integrity Constraints биват следните типове:

1. Domain constraints

Тук изхождаме от това, че дадено поле може да съдържа стойности само от предварително зададено множество – домейн. Елементите на предварително зададеното множество (домейн) на даденото поле, трябва да са от един и същ тип (това в случаят е домейна).

2. Entity integrity constraints

Тук изискването е относо Първичният ключ, и се състои в това, той да не е NULL, нито никоя част от него, ако е съставен, защото това би нарушило достъпността до даденият запис и би нарушило Първа нормалана форма.

Това ограничение изисква всяка таблица да има Супер ключ, бил той и Първичен ключ, и също, никое поле от тях да не може да има NULL стойност.

Също, ако някое от полетата може по принцип да има NULL стойности, то не трябва да се задава като Първичен ключ.

3. Referential Integrity Constraints

Това ограничение трябва да се спазва при релациите между от отделните таблици, при т.н. Foreign Keys.

4. Key constraints

Tук ограничението се прилага за да се запази уникалността на дадено поле или група полета ако имаме съставен или несъставен UNIQUE ключ.

5. Enterprise (semantic) constraints

Допълнителни, специфични за стойността на полето ограничения и изисквания към информацията, свързани с например – максимална дължина на символните низове (CHAR, VARCHAR…), максимална и минимална стойност на числените стойности и т.н…

Използват се за по-финна настройка на семантичната стойност на информацията.