-- Database by Doug -- Douglas Kline -- 9/28/2018 -- Primary Keys USE Northwind -- note that I'm starting out with a -- modified version of the Northwind.Categories table -- called DBBDCategories -- for demo purposes -- Primary Keys -- a primary key has two purposes: ---- to guarantee access to every record in a table ---- to uniquely distinguish a record from all other records in the table -- this is done by requiring a primary key to be: ---- NOT NULL ---- UNIQUE across all records in that table -- the NOT NULL makes sure that *at least one* column is NOT NULL -- and that there is a WHERE clause that will match on every record -- for example: -- WHERE categoryID = 7 -- guarantees one of: -- categories with an categoryID of 7 -- there is no record with an *unknown* ID that *might be* 7 -- the UNIQUE makes sure that you can make a request of records -- that guarantees at most one record -- for example: -- WHERE categoryID = 7 -- guarantees one of: -- a *single* record with the category with an categoryID of 7 -- no category - there is definitively no record with an categoryID of 7 --*************************************************** -- tables don't absolutely require a primary key -- however, guaranteed, unique access is extremely helpful in many situations -- (particularly Online Transaction Processing Systems /OLTPs) -- AND, there can be significant performance benefits to having a PK -- (for certain operations) -- Consider my somewhat modified DBBDCategories table from Northwind SELECT * FROM DBBDCategories -- I happen to know that CategoryID is the primary key of this table -- but how would you know otherwise? -- you could look in the object inspector on the left -- expand the database, the tables, the Categories table, the Columns -- note the key icon on the left of the CategoryID, and the 'PK' in parentheses -- (demo) -- another way would be to put the table into a diagram -- note the yellow key icon next to the CategoryID -- (demo) -- Finally, a really definitive way would be to script out the table -- and see the full definition of the table in SQL -- (demo) -- here is a slightly abbreviated/edited version of -- the SQL CREATE statment for the DBBDCategories table: --CREATE TABLE [dbo].[DBBDCategories] --( -- [CategoryID] [int] NOT NULL, -- [CategoryName] [nvarchar](15) NOT NULL, -- [Description] [ntext] NULL, -- [Picture] [image] NULL, -- CONSTRAINT [PK_DBBDCategories] PRIMARY KEY CLUSTERED -- ( -- [CategoryID] ASC -- ) --) -- note the NOT NULL for CategoryID -- this means that every insert and update will be checked to make sure -- that the CategoryID does not become NULL -- let's try it -- demo insert new NULL PK -- demo update PK to a NULL -- note the PRIMARY KEY specified as a CONSTRAINT -- this means that every insert and update will be checked to make sure -- that no two CategoryIDs, in the WHOLE TABLE, get duplicated -- let's try it -- demo insert duplicate PK -- demo update PK to a duplicate value -- let's review -- we are guaranteed that no record in the categories table has an unknown CategoryID -- we are guaranteed that no two records in the categories table have the same CategoryID -- in other words -- WHERE CategoryID = 8 -- guarantees to return either no record, or one record -- and we are guaranteed that there is no record -- with an *unknown* CategoryID which is actually 8 -- so what does a categoryID of 8 actually mean? --....? --....? -- NOTHING!! -- primary keys don't *need* to mean anything -- they just have to be UNIQUE and NOT NULL -- now let's look at the definition of -- the *actual* Categories table from the Northwind DB --CREATE TABLE [dbo].[Categories] --( -- [CategoryID] [int] IDENTITY(1,1) NOT NULL, -- ** note IDENTITY(1,1) -- [CategoryName] [nvarchar](15) NOT NULL, -- [Description] [ntext] NULL, -- [Picture] [image] NULL, -- CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED -- ** note PRIMARY KEY -- ( -- [CategoryID] ASC -- ) --) ON [PRIMARY] -- note the PRIMARY KEY in place of UNIQUE -- these are interchangeable, they mean the same thing -- however, also note the IDENTITY(1,1) -- this is an example of defining a *synthetic* primary key -- we are relinquishing to the DB engine, -- the task of providing PK values for this column -- specifically, the first PK value should be 1 -- the second PK value should be 1 + 1 -- the third PK value should be 2 + 1 -- the fourth PK value should be 3 + 1 -- in other words, begin with 1, and increment by 1 each time -- this also means that NO ONE ELSE, besides the DB engine -- can change the value of Categories.CategoryID -- (demo) try to change a PK value -- (demo) try to insert a PK value -- also, IDENTITY values are never re-used -- this guarantees uniqueness across the live table and all archives -- for example, if we archive CategoryID = 7 (move to another place) -- then end up reusing CategoryID = 7 for another record -- those two records can be confused for each other -- (demo) create a new record, delete it, show next PK value, skipped -- why is this good? -- HUMANS might accidentally re-use archived PK values -- also, columns that *mean* something may need to be changed -- it does exactly what is needed, and no more -- internal to the db engine, this can significantly improve performance -- in summary, -- primary keys need to be UNIQUE and NOT NULL, and nothing more -- this guarantees unique access to each record -- *synthetic* keys can be helpful in keeping all key values UNIQUE -- this is especially helpful in OLTP type systems -- foreshadowing ... -- primary keys also are referenced by FOREIGN KEYS -- see the video on FOREIGN KEYS! -- thanks for watching! -- Database by Doug -- Douglas Kline -- 9/28/2018 -- Primary Keys
Thursday, October 4, 2018
Primary Keys in Relational Databases
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment