Finding the right primary key - mysql

I have decided to set combination of three values as a primary key(composite key) for my database table.Most of the times the first two columns will be unique.But in a few cases they are both same at which time the third columns value will be always unique for that row.The problem is that the third column is a description which is any string that the user can enter.I know it is not recommended to have a user given string as a primary key.But is it okay to have it as a part of the composite key.I really see no other option.

If at all possible, you should add a surrogate primary key, meaning a key that is unique and has no business meaning whatsoever.
Composite primary keys very often turn out to be less 'stable' than anticipated - but if you MUST use one, using one or more component columns over which the user has little or no control (like created_timestamp) would be preferable.

Add a separate column called id and make it auto increment and use this column as a primary key.
Hope this will solve your problem.
Cheers.

Related

Choose primary key

I'm creating a table to track income and outcome. I have the following rows
type [can assume 3 values]
date [date of the transaction]
incomeAmout
incomeDescription
outcomeAmount
outcomeDescription
If I have date as primary then I won't be able to have multiple transaction in the same date. I could make all the rows as primary key but I'm not sure this is the best way to proceed. What would you suggest me to do? I read some topics about creating an auto incremental index but I'm wondering if I can make it without adding another attribute.
Thanks
Make an id column as a primary key. This will be your immutable record identifier.
You'll probably want to have some kind of randomized transaction identifier as well, something like a UUID or a value derived from the SHA256 hash of something. That way you can share these identifiers without revealing too much about your database structure or how many records there are in the database.
Then, if you need another key, add it as a UNIQUE index, or define whatever unique constraints you want to enforce as a compound key.
Your question should be: Surrogate Key vs. Natural Key
In your case, you have no choice but to use Surrogate Key: create a new field named "ID" and set it as Integer, Autoincrement, Primary Key.
BTW, Microsoft recommends use of Surrogate key as a good practice.

Why am I not allowed to have repeating IDs in the Primary Key column in MySQL

I am using MySQL Workbench 6.0 and importing a reasonably large (~55MB) .csv file. The first column consists of reference IDs and the second is dates. The reference IDs read in fine for the first day but when it comes to the second day (when the reference IDs should start to repeat) the information starts to become garbled, though the dates remain correct.
It is also worth noting that I did not have the UN box ticked when I made the table.
I am wondering what is going on here and whether anyone could help me.
Thanks!
A primary key is by definition unique. That's basically all: you cannot have a non-unique primary key, so if you have defined it as primary key, you cannot have repeating values.
solutions: make it a non-primary key / index, or add some uniqueness by making it a combined primary key with the date.

Making sure a table entry is unique

I have mysql database table for addresses, it contains separate columns for post code / street /town.
How can I make sure a full table entry is unique rather than just one of the columns alone?
Make a composite key on {post code, street, town}.
A key can be primary (PRIMARY KEY) or alternate (UNIQUE constraint).
BTW, can two different towns have the same post code? If not, you don't need the town in the key. In fact, consider normalizing your model by "extracting" the town to a separate table.
mysql allows you to have a unique key for n number of fields or columns. When you declare this column as unique , mysql checks for the constraint for duplication.
For more info read this mysql unique key
"The UNIQUE and PRIMARY KEY constraints both provide a guarantee for uniqueness for a column or set of columns."
But, i suggest the front end validation for making the user comfortable (just incase u had not thought of it ;) )
A database table may have multiple unique keys, so it will reject any INSERT queries that violate the constraints you set in the table.
Simply set the other columns to be unique and you should find that your problem is solved.

How to define a deferred constraint in MySQL

is it possible to create a primary key in a existing table on a column that have repeated value? I want is previous record not validate but new record will validate with this.Is it possible in mysql. I know it is possible in Oracle (here is an example) but don't have idea about mysql.
The link you posted as a comment to Nerd-Herd's answer uses deferred constraints. Those constraints are checked at the end of the transaction rather than at the time the statement is executed.
MySQL does not support deferred constraints
If you absolutely need deferred constraints and want to stick with an open source database you will need to migrate to PostgreSQL.
No it can not be. It violates what Primary Key means. But if you want to have a composite primary key, it may be possible
A primary key is always a unique identifier, if you make it non unique it stops being an identifier, why do you want to repeat it? If you have multiple entries that have a field that repeats, that field is not your primary key, however, you can combine it with another field that will give you a primary key (not very recommendable, but you can make this field plus a timestamp field your combined primary key).
In this case what I would recommend is make an autoincrement key and just use this field that repeats as a normal field, maybe ad an index to it to improve searches. You can still look for records on any field, just because it's not your primary key it doesn't mean you are not going to be able to search and get it. The idea of a primary key is that it will get you 1 and only 1 record, not 1 or more.

Deal with table that's composite primary key I wanted to include a nullable column

Assume a table that may look like this:
userId INT (foreign key to a users table)
profileId INT (foreign key to a profiles table)
value INT
Say that in this table preferences for users are saved. The preference should be loaded according to the current user and the profile that the current user has selected. That means that the combination of userId and profileId is unique and can be used as a composite primary key.
But then I want to add the ability to also save a default value that should be used if no value for a specific profileId is save in the database. My first idea would be to set the profileId column to nullable and say that the row that has null as profileId contains the default value. But then I can't use a composite primary key that involves this table, because nullable columns can't be part of a primary key.
So what's the "best" way to work around this? Just drop the primary key completely and go without primary key? Generate an identity column as primary key that I never need? Create a dummy profile to link to in the profile table? Create a separate table for default values (which is the only option that guarantees that no userId has multiple default values??)?
Update: I thought about Dmitry's answer but after all it has the drawback that I can't even create a unique constraint on the two columns userId and profileId (MySQL will allow duplicate values if profileId is null and DB2 will refuse to even create a unique constraint on a nullable column). So with Dmitry's solution I will have to live without this consistency check of the DB. Is that acceptable? Or is that not acceptable (after all consistency checks are a major feature of relational DBs). What is your reasoning?
Create ID autoincrement field for your primary key.
AND
Create unique index for (userId, profileId) pair. If necessary create dummy profile instead of null.
Dmitry's answer is a good one, but since your case involves what is essentially an intersection table, there is another good way to solve this. For your situation I also like the idea of creating a default user profile that you can use in your code to establish default settings. This is good because it keeps your data model clean without introducing extra candidate keys. You would need to be clear in this dummy/default profile that this is what it is. You can give it a clear name like "Default User" and make sure that nobody but the administrator has access to the user credentials.
One other advantage of this solution is that you can sign on as the default user and use your system's GUI to modify the defaults rather than having to fiddle with the data through DB access tools. Depending on the policies in your shop, direct access to the data tables by programmers may be hard or impossible. Using the tested/approved GUIs for modifying defaults removes a lot of red tape and prevents some kinds of accidental damage to the data.
Bottom Line: Primary keys are important. In a transactional system every table should have a at least one unique index one of which should be the primary key. You can always enforce this by adding a surrogate (auto increment) key to every table. Even if you do, you still generally want a natural unique index whenever possible. This is how you will generally find what you're looking for in a table.
Creating a Default User entry in your user table isn't a cheat or a hack, it's using your table structure the way it's meant to be used and it allows you to put a usable unique contraint on the combination of user ID and profile ID, regardless of whether you invent an additional, arbitrary unique constraint with a surrogate key.
This is the normal behaviour of UNIQUE constrain on a NULL column. It allows one row of data with NULL values. However, that is not the behaviour we want for this column. We want the column to accept unique values and also accept multiple NULL values.
This can be achieved using a computed column and adding a contraint to the computed column instead default null value.
Refer below article will help you more in this matter:
UNIQUE Column with multiple NULL values
I always always always use a primary auto_increment key on a table, even if its redundant; it just gives me a fantastically simple way to identify a record I want to access later or refer to elsewhere. I know it doesn't directly answer your question, but it does make the primary key situation simpler.
create table UserProfile ( int UserProfileID auto_increment primary key etc.,
UserID int not null, ProfileID int );
Then create a secondary index UserProfileIDX(UserID, ProfileID) that's unique, but not the primary key.