Related
In a DBMS we have
Superkey - An attribute or a set of attributes that uniquely identifies a row in a table.
Candidate Key - An attribute or set of attributes that uniquely identify identifies a row in a table. The difference between the superkey and a candidate key is no subset of a candidate key can itself be a candidate key.
Primary key - A chosen candidate key that become the attribute to uniquely identify a row.
If we want to identify a many to many relation between two tables we can define a junction table such as:
Tables:
Author(AuthorID, FirstName, LastName) -- AuthorID is primary key
Book(BookID, BookTitle) -- BookID is primary key
To create the relation between both:
AuthorBook(authorID, BookID) -- together authorID and BookID are primary key
I am thinking bookID and authorID are both primary keys in their own respect.
Since a candidate key (and therefore a primary key) must not have a subset containing a candidate key, how can authorID plus BookID be a primary key? This seems to break the definition of a primary key.
I understand this may be the difference between real world an theory but as the DBMS textbooks I have read seem to define junction tables this way and define primary keys this way it seems like there is a disconnect there.
Am I misunderstanding this concept?
When we use one of those terms we have to be talking about a given table (variable, value or expression). The superkeys, CKs & PKs of a table are not determined by roles its attributes play in other tables. They are determined by what valid values can arise for the table under the given business rules.
Superkey - An attribute or a set of attributes that uniquely identifies a row in a database.
A superkey of a given table can be defined as a set of attributes that "uniquely identifies a row" of the table. (Not database.) Although that quoted phrase is a kind of shorthand that isn't a very clear description if you don't already know what it means.
A superkey of a given table can be defined as a set of attributes whose subrow values can only appear once in the table. Or as a set of attributes that functionally determines every set of attributes in the table.
When a superkey has just one attribute we can sloppily talk about that attribute being a superkey.
Candidate Key - An attribute or set of attributes that uniquely identifies a row in a database.
It's true that every CK (candidate key) of a certain table is a superkey of that table. But you mean that a set of attributes is by definition a superkey when/iff that and some other condition(s) hold. But you don't clearly say that when you write this section.
The difference between the superkey and a candidate key is no subset of a candidate key can itself be a candidate key.
No. A set is a subset of itself so a CK is a subset of itself so a CK always has a subset that is a CK--itself. What you mean is, no proper/smaller subset. Then your statement is true. But also true and more important is that no proper/smaller subset of a CK is a superkey.
You don't actually define "CK" in this paragraph. A CK of a given table can be defined as a superkey of that table that contains no proper/smaller subset that is a superkey of that table.
Primary key - A chosen candidate key that becomes the attribute to uniquely identify a row.
No. The PK (primary key) of a given table is defined as the one CK of that table that you decided to call the PK. (Not attribute.)
Note that CKs & PKs are superkeys. PKs don't matter to relational theory.
To create the relation between both:
AuthorBook(authorID, BookID) -- together authorID and BookID are primary key
What the superkeys & CKs are & so what the PK can be is determined by the FDs (functional dependencies) that hold in the table. But if you are presuming that this is a many to many table then it takes an authorID-bookID pair to uniquely identify a row, so there can only be one CK, {authorID, bookID}. So that is the only possible PK. So {authorID} & {bookID} cannot be superkeys or CKs or PKs.
You can see this by looking at examples & applying the definitions.
authorID bookID
1 a
1 b
Here authorID does not uniquely identify a row. So it can't be a superkey. So it can't be a CK. So it can't be a PK.
textbooks I have read seem to define junction tables this way and define primary keys this way
No, they don't.
However they do say that certain sets of attributes & subsets of superkeys, CKs & PKs in the junction table are FKs (foreign keys) in the junction table referencing those other tables where they are CKs (which might be PKs) of/in those other tables.
A FK of a given table can be defined as a certain set of attributes in the table whose subrow values must appear as certain CK subrows in a certain other table.
But since you say this is a junction table, presumably {authorID} is a FK to an author table where its values appear under a CK/PK & {bookID} is a FK to a book table where its values appear under a CK/PK. So FK {authorID} in AuthorBook referencing {authorID} in Author & FK {bookID} in AuthorBook referencing {bookID} in Book.
PS PK & other terms mean something else in SQL. A declared SQL PK can have a smaller SQL UNIQUE declared within it. SQL "uniqueness" itself is defined in terms of SQL NULL. It's reasonable to say that an SQL PK is more reminiscent a relational superkey than it is reminiscent of a relational PK. Similarly a SQL FK is more reminiscent of what we could reasonably call a relational foreign superkey than a relational foreign key.
Defination of Superkey and Primary key in wikipedia
A superkey is a set of attributes within a table whose values can be used to uniquely identify a tuple.
and
The primary key has to consist of characteristics that cannot be duplicated by any other row. The primary key may consist of a single attribute or a multiple attributes in combination.
I've gone through many books and surfed on internet but what i found in them is what is primarykey and what is superkey.
But what i want to know is why superkey is required when we can identify a tuple uniquely through primarykey ?
Superkeys are defined for conceptual completeness. You never need a superkey for reference purposes. A reference to a primary key will do just fine.
The concept of superkeys can be useful when you are analyzing a body of data in order to discover all the functional dependencies in it.
Once you have discovered a key, the next question is whether or not it is a superkey. If is is, you turn your attention to the candidate key contained in the superkey.
Let's define what these terms mean in the first place:
A "superkey" is any set of attributes that, when taken together, uniquely identify rows in the table.
A minimal1 superkey is called "candidate key", or just "key".
All keys in the same table are logically equivalent, but for historical and practical reasons we choose one of them and call it "primary", while the remaining are "alternate" keys.
So, every primary key is key, but not every key is primary. Every key is superkey, but not every superkey is key.
Constraints that physically enforce keys in the database are: PRIMARY KEY constraint (for primary key) and UNIQUE constraint (for alternate key). These constraints should not be created on all superkeys, only on keys.
It is not unusual to have multiple keys in the same table, depending on the nature of your data. For example, a USER table might have unique USER_ID and unique USER_NAME. Since both of them need to be unique on their own, you must create2 both keys, even though only one of them is strictly needed for identification.
1 That is, a superkey that would stop being unique (and therefore, being a superkey) if any of the attributes were removed from it.
2 I.e. create PRIMARY KEY or UNIQUE constraint.
A word key is usually a short for a candidate key.
Superkey means a super-set of a key (key attributes and some more).
Irreducible superkey is called a candidate key. (Irreducible means that if you remove one attribute, it is not a key any more); in general, there is more than one candidate key for a given relation (actually a relational variable).
One candidate key that designer choses to prefer (for some reason) is called the primary key.
This was on a logical level, keys are defined for relational variables, so called relvars.
In physical implementation:
Relvar maps to a table.
Primary key to the primary key of the table.
Other candidate keys (except PK) map to alternate keys (unique not null).
A primary key is a superkey. Having only one such key constraint and only one way to identify tuples isn't necessarily sufficient.
Firstly, the relational model's versatility derives very much from the fact that it does not predetermine how data can or should be accessed in a table. A user or application is free to query a table based on whatever set of attributes may be necessary or convenient at the time. There is no obligation to use a "primary" key, which may or may not be relevant for some queries.
Secondly, uniqueness constraints (usually on candidate keys) are a data integrity feature. They guarantee data isn't duplicated in the key attributes. That kind of constraint is often useful on more than one set of attributes where business rules dictate that things should be unique. Uniqueness of one thing alone obviously doesn't guarantee uniqueness of another thing.
Thirdly, the query optimiser can take advantage of any and all keys as a way of optimising data access through query rewrites. From the optimiser's point of view the more keys it has to work with in a table the better.
I think superkey is just part of the relational algebra abstraction - your primary key is (likely) to be the minimal superkey but you might have other superkeys whereas you only have one primary key.
What meaning does the concept of a primary key have to the database engine of SQL Server? I don't mean the clustered/nonclustered index created on the "ID" column, i mean the constraint object "primary key". Does it matter if it exists or not?
Alternatives:
alter table add primary key clustered
alter table create clustered index
Does it make a difference?
In general, a KEY is a column (or combination of columns) that uniquely identifies each row in the table. It is possible to have multiple KEYs in a table (for example, you might have a Person table where both the social security number as well as an auto-increasing number are both KEYs).
The database designer chooses one of theses KEYs to be the PRIMARY KEY. Conceptually, it does not matter which KEY is chosen as the PRIMARY KEY. However, since the PRIMARY KEY is usually used to refer to entries in this table from other tables (through FOREIGN KEYs), choosing a good PRIMARY KEY can be relevant w.r.t. (a) performance and (b) maintainability:
(a) Since the primary key will usually be used in JOINs, the index on the primary key (its size, its distribution, ...) is much more relevant to performance than other indexes.
(b) Since the primary key is used as a foreign key in other tables, changing the primary key value is always a hassle, since all the foreign key values in the other tables need to be modified as well.
A PRIMARY KEY is a constraint - this is a logical object that says something about the rules that your data must adhere to. An index is an access structure - it says something about the way the machine can search through the data. To implement a PRIMARY KEY, most RDBMS-es use an index.
Some RDBMS-es (fe. MySQL) do not make the distinction between PRIMARY KEY or UNIQUE constraint and the index that is used to help implement it. But for example, Oracle does: in oracle you can do something like: ALTER TABLE t DROP pk KEEP INDEX. This is useful if you want to change the definition of the primary key (for example, you are replacing a natural primary key with a surrogate primary key) but you still want to have a unique constraint on the original primary key columns without rebuilding the index. That makes sense if the index is very large and would take considerable table and resources to rebuild.
From what I can see, MS SQL does not make the distinction. I mean a tool like Management studio does display "Keys", "Indexes" and "Constraints" in differrent folders, but changing the name of one immediately changes the name of the corresponding objects in the other folders. So I think here the distinction is not really present in this case.
I've been told that if I foreign key two tables, that SQL Server will create something akin to an index in the child table. I have a hard time believing this to be true, but can't find much out there related specifically to this.
My real reason for asking this is because we're experiencing some very slow response time in a delete statement against a table that has probably 15 related tables. I've asked our database guy and he says that if there is a foreign key on the fields, then it acts like an index. What is your experience with this? Should I add indexes on all foreign key fields or are they just unnecessary overhead?
A foreign key is a constraint, a relationship between two tables - that has nothing to do with an index per se.
However, it makes a lot of sense to index all the columns that are part of any foreign key relationship. An FK-relationship will often need to look up a relating table and extract certain rows based on a single value or a range of values.
So it makes good sense to index any columns involved in an FK, but an FK per se is not an index.
Check out Kimberly Tripp's excellent article "When did SQL Server stop putting indexes on Foreign Key columns?".
Wow, the answers are all over the map. So the Documentation says:
A FOREIGN KEY constraint is a candidate for an index because:
Changes to PRIMARY KEY constraints are checked with FOREIGN KEY constraints in related tables.
Foreign key columns are often used in join criteria when the data from related tables is combined in queries by matching the column(s) in the FOREIGN KEY constraint of one table with the primary or unique key column(s) in the other table. An index allows Microsoft® SQL Server™ 2000 to find related data in the foreign key table quickly. However, creating this index is not a requirement. Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
So it seems pretty clear (although the documentation is a bit muddled) that it does not in fact create an index.
No, there is no implicit index on foreign key fields, otherwise why would Microsoft say "Creating an index on a foreign key is often useful". Your colleague may be confusing the foreign key field in the referring table with the primary key in the referred-to table - primary keys do create an implicit index.
Foreign keys do not create indexes. Only alternate key constraints(UNIQUE) and primary key constraints create indexes. This is true in Oracle and SQL Server.
In PostgeSql you can check for indexes yourself if you hit \d tablename
You will see that btree indexes have been automatically created on columns with primary key and unique constraints, but not on columns with foreign keys.
I think that answers your question at least for postgres.
Say you have a big table called orders, and a small table called customers. There is a foreign key from an order to a customer. Now if you delete a customer, Sql Server must check that there are no orphan orders; if there are, it raises an error.
To check if there are any orders, Sql Server has to search the big orders table. Now if there is an index, the search will be fast; if there is not, the search will be slow.
So in this case, the slow delete could be explained by the absence of an index. Especially if Sql Server would have to search 15 big tables without an index.
P.S. If the foreign key has ON DELETE CASCADE, Sql Server still has to search the order table, but then to remove any orders that reference the deleted customer.
SQL Server autocreates indices for Primary Keys, but not for Foreign Keys. Create the index for the Foreign Keys. It's probably worth the overhead.
It depends. On MySQL an index is created if you don't create it on your own:
MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created.
Source: https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html
The same for MySQL 5.6 eh.
Strictly speaking, foreign keys have absolutely nothing to do with indexes, yes. But, as the speakers above me pointed out, it makes sense to create one to speed up the FK-lookups. In fact, in MySQL, if you don't specify an index in your FK declaration, the engine (InnoDB) creates it for you automatically.
Not to my knowledge. A foreign key only adds a constraint that the value in the child key also be represented somewhere in the parent column. It's not telling the database that the child key also needs to be indexed, only constrained.
I notice that Entity Framework 6.1 pointed at MSSQL does automatically add indexes on foreign keys.
I'm currently designing a brand new database. In school, we always learned to put a primary key in each table.
I read a lot of articles/discussions/newsgroups posts saying that it's better to use unique constraint (aka unique index for some db) instead of PK.
What's your point of view?
A Primary Key is really just a candidate key that does not allow for NULL. As such, in SQL terms - it's no different than any other unique key.
However, for our non-theoretical RDBMS's, you should have a Primary Key - I've never heard it argued otherwise. If that Primary Key is a surrogate key, then you should also have unique constraints on the natural key(s).
The important bit to walk away with is that you should have unique constraints on all the candidate (whether natural or surrogate) keys. You should then pick the one that is easiest to reference in a Foreign Key to be your Primary Key*.
You should also have a clustered index*. this could be your Primary Key, or a natural key - but it's not required to be either. You should pick your clustered index based on query usage of the table. When in doubt, the Primary Key is not a bad first choice.
Though it's technically only required to refer to a unique key in a foreign key relationship, it's accepted standard practice to greatly favor the primary key. In fact, I wouldn't be surprised if some RDBMS only allow primary key references.
Edit: It's been pointed out that Oracle's term of "clustered table" and "clustered index" are different than Sql Server. The equivalent of what I'm speaking of in Oracle-ese is an Index Ordered Table and it is recommended for OLTP tables - which, I think, would be the main focus of SO questions. I assume if you're responsible for a large OLAP data warehouse, you should already have your own opinions on database design and optimization.
Can you provide references to these articles?
I see no reason to change the tried and true methods. After all, Primary Keys are a fundamental design feature of relational databases.
Using UNIQUE to serve the same purpose sounds really hackish to me. What is their rationale?
Edit: My attention just got drawn back to this old answer. Perhaps the discussion that you read regarding PK vs. UNIQUE dealt with people making something a PK for the sole purpose of enforcing uniqueness on it. The answer to this is, If it IS a key, then make it key, otherwise make it UNIQUE.
A primary key is just a candidate key (unique constraint) singled out for special treatment (automatic creation of indexes, etc).
I expect that the folks who argue against them see no reason to treat one key differently than another. That's where I stand.
[Edit] Apparently I can't comment even on my own answer without 50 points.
#chris: I don't think there's any harm. "Primary Key" is really just syntactic sugar. I use them all the time, but I certainly don't think they're required. A unique key is required, yes, but not necessarily a Primary Key.
It would be very rare denormalization that would make you want to have a table without a primary key. Primary keys have unique constraints automatically just by their nature as the PK.
A unique constraint would be used when you want to guarantee uniqueness in a column in ADDITION to the primary key.
The rule of always have a PK is a good one.
http://msdn.microsoft.com/en-us/library/ms191166.aspx
You should always have a primary key.
However I suspect your question is just worded bit misleading, and you actually mean to ask if the primary key should always be an automatically generated number (also known as surrogate key), or some unique field which is actual meaningful data (also known as natural key), like SSN for people, ISBN for books and so on.
This question is an age old religious war in the DB field.
My take is that natural keys are preferable if they indeed are unique and never change. However, you should be careful, even something seemingly stable like a persons SSN may change under certain circumstances.
Unless the table is a temporary table to stage the data while you work on it, you always want to put a primary key on the table and here's why:
1 - a unique constraint can allow nulls but a primary key never allows nulls. If you run a query with a join on columns with null values you eliminate those rows from the resulting data set because null is not equal to null. This is how even big companies can make accounting errors and have to restate their profits. Their queries didn't show certain rows that should have been included in the total because there were null values in some of the columns of their unique index. Shoulda used a primary key.
2 - a unique index will automatically be placed on the primary key, so you don't have to create one.
3 - most database engines will automatically put a clustered index on the primary key, making queries faster because the rows are stored contiguously in the data blocks. (This can be altered to place the clustered index on a different index if that would speed up the queries.) If a table doesn't have a clustered index, the rows won't be stored contiguously in the data blocks, making the queries slower because the read/write head has to travel all over the disk to pick up the data.
4 - many front end development environments require a primary key in order to update the table or make deletions.
Primary keys should be used in situations where you will be establishing relationships from this table to other tables that will reference this value. However, depending on the nature of the table and the data that you're thinking of applying the unique constraint to, you may be able to use that particular field as a natural primary key rather than having to establish a surrogate key. Of course, surrogate vs natural keys are a whole other discussion. :)
Unique keys can be used if there will be no relationship established between this table and other tables. For example, a table that contains a list of valid email addresses that will be compared against before inserting a new user record or some such. Or unique keys can be used when you have values in a table that has a primary key but must also be absolutely unique. For example, if you have a users table that has a user name. You wouldn't want to use the user name as the primary key, but it must also be unique in order for it to be used for log in purposes.
We need to make a distinction here between logical constructs and physical constructs, and similarly between theory and practice.
To begin with: from a theoretical perspective, if you don't have a primary key, you don't have a table. It's just that simple. So, your question isn't whether your table should have a primary key (of course it should) but how you label it within your RDBMS.
At the physical level, most RDBMSs implement the Primary Key constraint as a Unique Index. If your chosen RDBMS is one of these, there's probably not much practical difference, between designating a column as a Primary Key and simply putting a unique constraint on the column. However: one of these options captures your intent, and the other doesn't. So, the decision is a no-brainer.
Furthermore, some RDBMSs make additional features available if Primary Keys are properly labelled, such as diagramming, and semi-automated foreign-key-constraint support.
Anyone who tells you to use Unique Constraints instead of Primary Keys as a general rule should provide a pretty damned good reason.
the thing is that a primary key can be one or more columns which uniquely identify a single record of a table, where a Unique Constraint is just a constraint on a field which allows only a single instance of any given data element in a table.
PERSONALLY, I use either GUID or auto-incrementing BIGINTS (Identity Insert for SQL SERVER) for unique keys utilized for cross referencing amongst my tables. Then I'll use other data to allow the user to select specific records.
For example, I'll have a list of employees, and have a GUID attached to every record that I use behind the scenes, but when the user selects an employee, they're selecting them based off of the following fields: LastName + FirstName + EmployeeNumber.
My primary key in this scenario is LastName + FirstName + EmployeeNumber while unique key is the associated GUID.
posts saying that it's better to use unique constraint (aka unique index for some db) instead of PK
i guess that the only point here is the same old discussion "natural vs surrogate keys", because unique indexes and pk´s are the same thing.
translating:
posts saying that it's better to use natural key instead of surrogate key
I usually use both PK and UNIQUE KEY. Because even if you don't denote PK in your schema, one is always generated for you internally. It's true both for SQL Server 2005 and MySQL 5.
But I don't use the PK column in my SQLs. It is for management purposes like DELETEing some erroneous rows, finding out gaps between PK values if it's set to AUTO INCREMENT. And, it makes sense to have a PK as numbers, not a set of columns or char arrays.
I've written a lot on this subject: if you read anything of mine be clear that I was probably referring specifically to Jet a.k.a. MS Access.
In Jet, the tables are physically ordered on the PRIMARY KEY using a non-maintained clustered index (is clustered on compact). If the table has no PK but does have candidate keys defined using UNIQUE constraints on NOT NULL columns then the engine will pick one for the clustered index (if your table has no clustered index then it is called a heap, arguably not a table at all!) How does the engine pick a candidate key? Can it pick one which includes nullable columns? I really don't know. The point is that in Jet the only explicit way of specifying the clustered index to the engine is to use PRIMARY KEY. There are of course other uses for the PK in Jet e.g. it will be used as the key if one is omitted from a FOREIGN KEY declaration in SQL DDL but again why not be explicit.
The trouble with Jet is that most people who create tables are unaware of or unconcerned about clustered indexes. In fact, most users (I wager) put an autoincrement Autonumber column on every table and define the PRIMARY KEY solely on this column while failing to put any unique constraints on the natural key and candidate keys (whether an autoincrement column can actually be regarded as a key without exposing it to end users is another discussion in itself). I won't go into detail about clustered indexes here but suffice to say that IMO a sole autoincrement column is rarely to ideal choice.
Whatever you SQL engine, the choice of PRIMARY KEY is arbitrary and engine specific. Usually the engine will apply special meaning to the PK, therefore you should find out what it is and use it to your advantage. I encourage people to use NOT NULL UNIQUE constraints in the hope they will give greater consideration to all candidate keys, especially when they have chosen to use 'autonumber' columns which (should) have no meaning in the data model. But I'd rather folk choose one well considered key and used PRIMARY KEY rather than putting it on the autoincrement column out of habit.
Should all tables have a PK? I say yes because doing otherwise means at the very least you are missing out on a slight advantage the engine affords the PK and at worst you have no data integrity.
BTW Chris OC makes a good point here about temporal tables, which require sequenced primary keys (lowercase) which cannot be implemented via simple PRIMARY KEY constraints (SQL key words in uppercase).
PRIMARY KEY
1. Null
It doesn’t allow Null values. Because of this we refer PRIMARY KEY =
UNIQUE KEY + Not Null CONSTRAINT.
2. INDEX
By default it adds a clustered index.
3. LIMIT
A table can have only one PRIMARY KEY Column[s].
UNIQUE KEY
1. Null
Allows Null value. But only one Null value.
2. INDEX
By default it adds a UNIQUE non-clustered index.
3. LIMIT
A table can have more than one UNIQUE Key Column[s].
If you plan on using LINQ-to-SQL, your tables will require Primary Keys if you plan on performing updates, and they will require a timestamp column if you plan on working in a disconnected environment (such as passing an object through a WCF service application).
If you like .NET, PK's and FK's are your friends.
I submit that you may need both. Primary keys by nature need to be unique and not nullable. They are often surrogate keys as integers create faster joins than character fileds and especially than multiple field character joins. However, as these are often autogenerated, they do not guarantee uniqueness of the data record excluding the id itself. If your table has a natural key that should be unique, you should have a unique index on it to prevent data entry of duplicates. This is a basic data integrity requirement.
Edited to add: It is also a real problem that real world data often does not have a natural key that truly guarantees uniqueness in a normalized table structure, especially if the database is people centered. Names, even name, address and phone number combined (think father and son in the same medical practice) are not necessarily unique.
I was thinking of this problem my self. If you are using unique, you will hurt the 2. NF. According to this every non-pk-attribute has to be depending on the PK. The pair of attributes in this unique constraint are to be considered as part of the PK.
sorry for replying to this 7 years later but didn't want to start a new discussion.