Warning message for a primary key constraint - sql

I have a problem with assigning a primary key in one of the tables containing employee info. There is no unique column in that table, The only option I am left with is taking combination of three columns as a primary key.
But it gives a warning message as Warning! The maximum key length is 900 bytes. The index 'pk_hrempid' has maximum length of 1530 bytes.For some combination of large values, the insert/update operation will fail I came to know that this would be a major problem in the future for inserting the data. Is there a solution for this warning?
Other question is can I put an auto-increment value as a unique id, is it recommended? I want to make sure that it does not give problems in the future as I have many tables containing employee info from the other departments. Some employees may be present in two or more tables
Any help is appreciated!

Whilst is it sounds from your attempt at a compound primary key that you're attempting the best-practice of using a "natural key", there's nothing 'wrong' with using an auto-incrementing ID field.
If your suggested fields are too large to be used as a key, perhaps they weren't the best choice in the first place. Could you add another "natural" key column with a better datatype perhaps?
Don't forget to take into account the optimizations that are possible by choosing good indexes and suitable datatypes for tables that are going to be heavily-queried.

This is a limitation of a primary key. You can not have a PK larger that 900 bytes.
You could add a identity column to the table and set it as the primary key. I prefer to use Guids as they are globally unique.

I'd go with an auto-increment type solution for the primary key, problem with using personal data for this sort of thing is that you cannot guarantee uniqueness which is the fundamental requirement of a primary key.

Related

Can I set this column as the primary key?

I'm new to SQL Server and would really appreciate it if you could help me out here.
So are a healthcare provider and internally we assign an ID to each patient (for example, 1234). I'm currently constructing another database, and I just wonder can I use our internal IDs as primary key, given they are unique? If so, since I am not going to do any calculation on the primary key, can I set them to string/char datatype for primary key?
In short, yes you can but it is not recommended at all!
To give you some heads up:
Primary keys should never change
You cannot use a natural key or a key form other system
They cannot have any formula
Use short but suitable key type
If you have an external key that you want to use to find some patients, create another column for it and add UNIQUE Constraint to it.
just don't forget to add index for that column
Read this post of mine for more information:
http://pilpag.blogspot.dk/2016/06/relational-database-designsimple-rules.html
The conditions for a primary key are that the key is unique in the table and never NULL.
Your patient id would appear to have these characteristics.
That said, there are good reasons for developing a synthetic primary key (auto-incremented/identity/serial depending on the database). More importantly, the actual patient ID may be sensitive information. For instance, patients might use the id when logging in or it might be printed on invoices.
It might not be a good idea to have sensitive information repeated throughout the database. For this reason, an "internal" id would be used to refer to patients in table and all the sensitive information would be contained in one or a handful of tables.
This would perhaps be more obvious if the "patient id" were a government id ("social security number") or email address.
Yes, but the ID can also be numeric and a primary key - it doesn't have to be a string. As long as the ID is unique, you should be fine.
Yes, you can use your internal IDs if they are unique;PK limit is 900 bytes for char/varchar data types.So if your IDs are int is fine. But if your IDs can change with time or can be reused them for more than one patient I strong recommend not to use them to avoid chaos. I prefer a surrogate key, like an identity
If I understand correctly, you are assigning each patient a number so as to uniquely identify them. So a report would contain the patient number rather than only a patient's name which can be ambiguous. You won't ever change the patient numbers, because then you'd have to change this in all databases and would have to re-print all documents on the patient that are still needed. This makes this number a perfect primary key for a patient table in any of your databases.
You could use a generated technical ID instead as the table's primary key and have the patient number only as another field in the table (which would still have a unique constraint of course, because it is still the business key uniquely identifying a patient). Whether to do this or not is mainly a matter of personal preference and experience. I prefer natural keys over IDs (so I would make the patient number the primary key). This stems from having worked with rather large databases with thousands of tables and much hierarchy where the natural keys proved to result in faster queries, enhanced data consistency and easier maintenance. Others may have different experience, though.
So yes, the patient number seems to be the perfect natural primary key in my opinion.

SQL Server: How to allow duplicate records on small table

I have a small table "ImgViews" that only contains two columns, an ID column called "imgID" + a count column called "viewed", both set up as int.
The idea is to use this table only as a counter so that I can track how often an image with a certain ID is viewed / clicked.
The table has no primary or foreign keys and no relationships.
However, when I enter some data for testing and try entering the same imgID multiple times it always appears greyed out and with a red error icon.
Usually this makes sense as you don't want duplicate records but as the purpose is different here it does make sense for me.
Can someone tell me how I can achieve this or work around it ? What would be a common way to do this ?
Many thanks in advance, Tim.
To address your requirement to store non-unique values, simply remove primary keys, unique constraints, and unique indexes. I expect you may still want a non-unique clustered index on ImgID to improve performance of aggregate queries that would otherwise require a scan the entire table and sort. I suggest you store an insert timestamp, not to provide uniqueness, but to facilitate purging data by date, should the need arise in the future.
You must have some unique index on that table. Make sure there is no unique index and no unique or primary key constraint.
Or, SSMS simply doesn't know how to identify the row that was just inserted because it has no key.
It is generally not best practice to have a table without a (logical) primary key. In your case, I'd make the image id the primary key and increment the counter. The MERGE statement is well-suited for performing and insert or update at the same time. Alternatives exist.
If you don't like that, create a surrogate primary key (an identity column set as the primary key).
At the moment you have no way of addressing a specific row. That makes the table a little unwieldy.
If you allow multiple rows being absolutely identical, how would you update/delete one of those rows?
How would you expect the database being able to "know" what row you referred to??
At the very least add a separate identity column (preferred being the clustered index, too).
As a side note: It's weird that you "like to avoid unneeded data" but at the same time insert duplicates over and over again instead of simply add up the click count per single image...
Use SQL statements, not GUI, if the table has not primary key or unique constraint.

Can you use GUID for a column if column is not a primary key?

I have two columns in a database. Both are ids. I am making one numeric auto incremented. This is what I chose as the primary key.But the other column has to contain unique auto generated ids as well. There have to be different from the ids of the primary key (ie. the numeric auto increment column). Thus I was thinking of using GUID for this column. BUT:
Can you use GUID for a column if column is not a primary key?
Is it good practice?
Clearly, the GUID column will be unique, but it is rather big for joining purposes. So, it can be desirable to use the numeric column within the database for foreign key joins (joining on 4 byte or 8 byte integer quantities) rather than the 16 byte GUID column (unless you store it as a string, in which case it has 32 hex digits plus 4 dashes). The indexes will be smaller for the numeric column; the referencing tables will be smaller; the join comparisons will be quicker.
So, there might well be good reasons to have both, and to have the GUID as a secondary (alternative) unique key on the table rather than as the primary key.
This is possible and seems no problem except data size and some performance overhead.
As for me it is normal practice if you need to sync data in the table with some external system. Then you use guid to maintain global record identifier for synchronization and numeric primary key for relations inside database because they are faster than guid's.
Yes, you can. Whether it's a good idea depends on circumstance, but in general there's no issue here. Furthermore, you should probably create a 'unique key' on that column to enforce referential integrity (doing this will also allow you to create foreign keys that relate back to this column).
Just make sure you don't create a clustered index on that column!

Relational database design question - Surrogate-key or Natural-key?

Which one is the best practice and Why?
a) Type Table, Surrogate/Artificial Key
Foreign key is from user.type to type.id:
b) Type Table, Natural Key
Foreign key is from user.type to type.typeName:
I believe that in practice, using a natural key is rarely the best option. I would probably go for the surrogate key approach as in your first example.
The following are the main disadvantages of the natural key approach:
You might have an incorrect type name, or you may simply want to rename the type. To edit it, you would have to update all the tables that would be using it as a foreign key.
An index on an int field will be much more compact than one on a varchar field.
In some cases, it might be difficult to have a unique natural key, and this is necessary since it will be used as a primary key. This might not apply in your case.
The first one is more future proof, because it allows you to change the string representing the type without updating the whole user table. In other words you use a surrogate key, an additional immutable identifier introduced for the sake of flexibility.
A good reason to use a surrogate key (instead of a natural key like name) is when the natural key isn't really a good choice in terms of uniqueness. In my lifetime i've known no fewer than 4 "Chris Smith"s. Person names are not unique.
I prefer to use the surrogate key. It is often people will identity and use the natural key which will be fine for a while, until they decide they want to change the value. Then problems start.
You should probably always use an ID number (that way if you change the type name, you don't need to update the user table) it also allows you to keep your datasize down, as a table full of INTs is much smaller than one full of 45 character varchars.
If typeName is a natural key, then it's probably the preferable option, because it won't require a join to get the value.
You should only really use a surrogate key (id) when the name is likely to change.
Surrogate key for me too, please.
The other might be easier when you need to bang out some code, but it will eventually be harder. Back in the day, my tech boss decided using an email addr as a primary key was a good idea. Needless to say, when people wanted to change their addresses it really sucked.
Use natural keys whenever they work. Names usually don't work. They are too mutable.
If you are inventing your own data, you might as well invent a syntheic key. If you are building a database of data provided by other people or their software, analyze the source data to see how they identify things that need identification.
If they are managing data at all well, they will have natural keys that work for the important stuff. For the unimportant stuff, suit yourself.
well i think surrgote key is helpful when you don't have any uniquely identified key whose value is related and meaningful as is to be its primary key... moreover surrgote key is easier to implement and less overhead to maintain.
but on the other hand surrgote key is sometimes make extra cost by joining tables.
think about 'User' ... I have
UserId varchar(20), ID int, Name varchar(200)
as the table structure.
now consider that i want to take a track on many tables as who is inserting records... if i use Id as a primary key, then [1,2,3,4,5..] etc will be in foreign tables and whenever i need to know who is inserting data i've to join User Table with it because 1,2,3,4,5,6 is meaningless. but if i use UserId as a primary key which is uniquely identified then on other foreign tables [john, annie, nadia, linda123] etc will be saved which is sometimes easily distinguishable and meaningful . so i need not to join user table everytime when i do query.
but mind it, it takes some extra physical space as varchar is saved in foreign tables which takes extra bytes.. and ofcourse indexing has a significant performance issue where int performs better rather than varchar
Surrogate key is a substitution for the natural primary key.
It is just a unique identifier or number for each row that can be used for the primary key to the table.
The only requirement for a surrogate primary key is that it is unique for each row in the table.
It is useful because the natural primary key (i.e. Customer Number in Customer table) can change and this makes updates more difficult.

SQL: what exactly do Primary Keys and Indexes do?

I've recently started developing my first serious application which uses a SQL database, and I'm using phpMyAdmin to set up the tables. There are a couple optional "features" I can give various columns, and I'm not entirely sure what they do:
Primary Key
Index
I know what a PK is for and how to use it, but I guess my question with regards to that is why does one need one - how is it different from merely setting a column to "Unique", other than the fact that you can only have one PK? Is it just to let the programmer know that this value uniquely identifies the record? Or does it have some special properties too?
I have no idea what "Index" does - in fact, the only times I've ever seen it in use are (1) that my primary keys seem to be indexed, and (2) I heard that indexing is somehow related to performance; that you want indexed columns, but not too many. How does one decide which columns to index, and what exactly does it do?
edit: should one index colums one is likely to want to ORDER BY?
Thanks a lot,
Mala
Primary key is usually used to create a numerical 'id' for your records, and this id column is automatically incremented.
For example, if you have a books table with an id field, where the id is the primary key and is also set to auto_increment (Under 'Extra in phpmyadmin), then when you first add a book to the table, the id for that will become 1'. The next book's id would automatically be '2', and so on. Normally, every table should have at least one primary key to help identifying and finding records easily.
Indexes are used when you need to retrieve certain information from a table regularly. For example, if you have a users table, and you will need to access the email column a lot, then you can add an index on email, and this will cause queries accessing the email to be faster.
However there are also downsides for adding unnecessary indexes, so add this only on the columns that really do need to be accessed more than the others. For example, UPDATE, DELETE and INSERT queries will be a little slower the more indexes you have, as MySQL needs to store extra information for each indexed column. More info can be found at this page.
Edit: Yes, columns that need to be used in ORDER BY a lot should have indexes, as well as those used in WHERE.
The primary key is basically a unique, indexed column that acts as the "official" ID of rows in that table. Most importantly, it is generally used for foreign key relationships, i.e. if another table refers to a row in the first, it will contain a copy of that row's primary key.
Note that it's possible to have a composite primary key, i.e. one that consists of more than one column.
Indexes improve lookup times. They're usually tree-based, so that looking up a certain row via an index takes O(log(n)) time rather than scanning through the full table.
Generally, any column in a large table that is frequently used in WHERE, ORDER BY or (especially) JOIN clauses should have an index. Since the index needs to be updated for evey INSERT, UPDATE or DELETE, it slows down those operations. If you have few writes and lots of reads, then index to your hear's content. If you have both lots of writes and lots of queries that would require indexes on many columns, then you have a big problem.
The difference between a primary key and a unique key is best explained through an example.
We have a table of users:
USER_ID number
NAME varchar(30)
EMAIL varchar(50)
In that table the USER_ID is the primary key. The NAME is not unique - there are a lot of John Smiths and Muhammed Khans in the world. The EMAIL is necessarily unique, otherwise the worldwide email system wouldn't work. So we put a unique constraint on EMAIL.
Why then do we need a separate primary key? Three reasons:
the numeric key is more efficient
when used in foreign key
relationships as it takes less space
the email can change (for example
swapping provider) but the user is
still the same; rippling a change of
a primary key value throughout a schema
is always a nightmare
it is always a bad idea to use
sensitive or private information as
a foreign key
In the relational model, any column or set of columns that is guaranteed to be both present and unique in the table can be called a candidate key to the table. "Present" means "NOT NULL". It's common practice in database design to designate one of the candidate keys as the primary key, and to use references to the primary key to refer to the entire row, or to the subject matter item that the row describes.
In SQL, a PRIMARY KEY constraint amounts to a NOT NULL constraint for each primary key column, and a UNIQUE constraint for all the primary key columns taken together. In practice many primary keys turn out to be single columns.
For most DBMS products, a PRIMARY KEY constraint will also result in an index being built on the primary key columns automatically. This speeds up the systems checking activity when new entries are made for the primary key, to make sure the new value doesn't duplicate an existing value. It also speeds up lookups based on the primary key value and joins between the primary key and a foreign key that references it. How much speed up occurs depends on how the query optimizer works.
Originally, relational database designers looked for natural keys in the data as given. In recent years, the tendency has been to always create a column called ID, an integer as the first column and the primary key of every table. The autogenerate feature of the DBMS is used to ensure that this key will be unique. This tendency is documented in the "Oslo design standards". It isn't necessarily relational design, but it serves some immediate needs of the people who follow it. I do not recommend this practice, but I recognize that it is the prevalent practice.
An index is a data structure that allows for rapid access to a few rows in a table, based on a description of the columns of the table that are indexed. The index consists of copies of certain table columns, called index keys, interspersed with pointers to the table rows. The pointers are generally hidden from the DBMS users. Indexes work in tandem with the query optimizer. The user specifies in SQL what data is being sought, and the optimizer comes up with index strategies and other strategies for translating what is being sought into a stategy for finding it. There is some kind of organizing principle, such as sorting or hashing, that enables an index to be used for fast lookups, and certain other uses. This is all internal to the DBMS, once the database builder has created the index or declared the primary key.
Indexes can be built that have nothing to do with the primary key. A primary key can exist without an index, although this is generally a very bad idea.