Database Design: optional, but must be unique if provided a value - mysql

I have a column in one of my tables. It's optional, so it can be left blank. However, if a value is provided for that column, it must be unique. Two questions:
How do I implement this in my database design (I'm using MySQL Workbench, by the way)
Is there a potential problem with my model?

Just use a UNIQUE index on the column. See:
http://dev.mysql.com/doc/refman/5.1/en/create-index.html
A UNIQUE index creates a constraint
such that all values in the index must
be distinct. An error occurs if you
try to add a new row with a key value
that matches an existing row. For all
engines, a UNIQUE index permits
multiple NULL values for columns that
can contain NULL. If you specify a
prefix value for a column in a UNIQUE
index, the column values must be
unique within the prefix.

It's can be null (and not blank) and unique. By default value can be null. There is no problem for me.

You can create a UNIQUE index on a table. In MySQL workbench that is the UQ checkbox when creating/editing the table.

Step 1, ALTER the table and MODIFY the field so NULLs are allowed.
ALTER TABLE my_table MODIFY my_field VARCHAR(100) NULL DEFAULT NULL;
Step 2, add a UNIQUE index on the field.
ALTER TABLE my_table ADD UNIQUE INDEX U_my_field (my_field);
It's fine to use -- my only hesitation with putting a UNIQUE index on a nullable field it that it is slightly counter-intuitive at first glance.

1) Move the column to a new table, make it unique and non-nullable. You can now have a row in this new table only when you have a value for it.
2) Yes. Keys and dependencies on keys are the basis of data integrity in a relational database design. If an attribute is supposed to be unique then it should be implemented as a key. A nullable "key" is not a key at all and anyway is never necessary because it can always be moved to a new table and made non-nullable without loss of any information.

Related

MSQL unique constraint check only onward insert records Not already existing records

The table already has duplicates entries. I want to create a unique constraint in MQSL DB without deleting the existing duplicates. If any duplicate entries coming onwards then it will show an error. Given blow queries not working in MYSQL.
ALTER TABLE presence
ADD CONSTRAINT present uniqueness UNIQUE (employee_id,roll_number) where id >10000;
or
ALTER TABLE presence
ADD CONSTRAINT present uniqueness UNIQUE (employee_id,roll_number) where id <> (343,34534,34534)
Do we have something like that solution in SQL?
Add an additional column to the table that indicates the existing values.
Set it to NULL for the existing values. And give it a constant value, say 1, for the new rows. Then create a unique index or constraint on this column:
alter table t add constraint unique (employee_id, is_old)
Actually, I realize that you probably don't want duplicates with singleton old values and new values. That is just an issue of setting the value to NULL only for duplicates in the history. So, one row would have a constant value (say 1) in the historical data.
MySQL allows duplicate values on NULL, which is why this works.

What's the point of using AUTO_INCREMENT and PRIMARY KEY at the same time in MySQL?

In MySQL, I understand below
AUTO_INCREMENT: used to make INT value to increase automatically every time a user creates a row.
PRIMARY KEY: used to make value unique in that table.
However, I oftentimes see them used together when defining id.
I don't understand the point of using AUTO_INCREMENT with PRIMARY KEY since AUTO_INCREMENT itself would make id unique.
Is there any reason they are used together when creating id?
The primary key has three properties:
It is unique.
It is non-null.
There is only one per table.
Defining the key as a primary key means that it should also be used for foreign key references.
In addition, MySQL clusters the data by the primary key. So the declaration instructs new rows to go at the "end" of the table -- meaning adjacent to the most recent inserts on the data pages.
In addition, duplicate values for the auto-incremented id could be created in various ways. One way is that the increment counter can be reset, causing duplicates. MySQL should be pretty thread-safe on duplicates for concurrent updates, but bugs have been reported. As a primary key, no duplicates will be allowed into the table.
You understand it correctly, but they are doing different things.
PRIMARY KEY with AUTO_INCREMENT means we want this column isn't duplicate on the value and it will be auto increase if we didn't set the value.
but how about we only set AUTO_INCREMENT it only means it will be auto increase if we didn't set the value. but didn't make sure the value is unique.
AUTO_INCREMENT doesn't make the column uniqe. It only "automatically" fills a value when creating a row, if missing. But you can later update the values, or also create a row by explicitly providing the value.
PRIMARY KEY denies any modification sql statement that would cause 2 different entries storing equal values. So it guarantees you, that your DB is in a correct state.

Creating Duplication constraint on mysql table

I have the following table, I am trying to create a constraint on the table that states that the Ter_ID column can have the same Ter_ID repeating however the corresponding Status cannot be the same at anytime, so if for example one is trying to update Ter_ID 100P Status from U to A it wouldn't go through seeing that there is already a row with the corresponding data.
Ter_ID Status Address
100P A Road1
100P U Road2
200R A Road2
You need to add a composed unique index using the two columns.
Example:
ALTER TABLE `tablename` ADD UNIQUE `unique_index`(`Ter_ID`, `Status`);
Be aware of the different NULL behaviour depending of the MySQL engine that you are using. From the official MySQL documentation:
A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. This constraint does not apply to NULL values except for the BDB storage engine. For other engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL. If you specify a prefix value for a column in a UNIQUE index, the column values must be unique within the prefix.

Is there a way to make an entire MySQL row unique

I have a table in MySQL with 30 columns and thousands of entries.
Is there a way I could make every row unique, that means if a row already exists, I should not be able to enter that row again.
I can't use primary or unique keys here, because individually every column might be repeated.
I want the row to be unique.
for example:-There are is a table with
columns->name,age,height,weight.
In this column I can't make any one or two columns unique but I should not have two entries with all the same data.
You can make a unique index that includes all of the columns in your table
ALTER TABLE buyers ADD UNIQUE idx_row_unique(first_name,last_name,...);
This way you can keep a unique AUTO INCREMENT primary key for join purposes, while still ensuring that all of the data in your table is unique.
You need a composite primary key.
A composite primary key tells MySQL that you want your primary key to be a combination of fields.
More info here:
Why use multiple columns as primary keys (composite primary key)
You may create UNIQUE key on all the columns, not individual unique keys on each column. This means that the combination of the values will be unique - exactly what you need. But please note, that if any column allows null value, if the column contains null value, it will be counted as unique, even if another row contains the same values, with null for the same value.
You can make a unique index on more than one column. Just put all the columns in the index. If the columns are large you may run into issues with the maximum length of an index, but try it first and see.
You can hash the data and set the hash value as your PK, this will ensure that the rows are unique.

Getting underlying Primary Key in MySQL (InnoDB)

It is my understanding that when I make a table without a primary key that MySQL creates a sort of underlying primary key that it uses internally.
I am working with a table that does not have a primary key, but it would be very useful for my application if I could somehow access this value, assuming it does in fact exist and is retrievable.
So, I am wanting to know if I am correct in believing that such a value exists somewhere and also if it is possible to get that value.
Edit: just to make it clear, it would be very useful for my application for this table to have an incrementing int attribute. Unfortunately, it was not implemented that way. So, I am sort of grasping at straws to find a solution. What I am trying to do is select every nth row in the table (n changes). So, as you can see if there was this key, this would be very simple.
If a table has no primary key then there's no way of specifying a specific row within it because there is no way to uniquely identify an item. Even if you use a query that specifies a specific value for every column that still wouldn't be certain to only return a single row as without a primary key there's nothing to prevent duplicate rows.
However, a primary key is simply a unique index. If a table has a unique index on one or more of its columns and those columns don't accept NULLs then this is the primary key for the table in all but name.
If you table has no unique columns then you've got nothing to go on. You'll have to either make one column or combination of columns (for a composite key) unique, or add a column that serves as the primary key for the table. Fortunately it's relatively easy to add columns to a MySQL table, just add a primary key autoincrement column to the existing table.