Unique Constraint with conditions in MYSQL - mysql

In postgres we have a constraint defined that essentially allows us to limit the number of entries in a table with a certain value to one. We created this constraint:
create unique index list$default$uk on list_group(visitor_uid) where list_type = 'default';
Which means that the unique constraint is only applied when the list_type='default' so that there can only be one 'default' list per visitor in the table.
It looks like MySql doesn't support the additional where on the unique constraint. Is there another way to support this in the database schema for MySQL?

MYSQL doesn't support such types of constraints.
You should use stored procudures for inserting data instead, so you can do some checking and validation.
Why don't you define your default as such that it must have 1 as primary key? This way a normal unique constraint on the pk would be enough already.
If nothing fits to you, you could also consider changing your data model.

Actually it exists. Most contraints depend on the table Engine.
I think InnoDB supports this.
To do it, you have to add a UNIQUE index with the unique combination:
ALTER TABLE visitor ADD UNIQUE unique_default_visitor( visitor_uid, list_type );

I supposed you'd have to write a trigger to check for it.

I never use MySQL but maybe you can create an index like this:
CREATE UNIQUE INDEX list$default$uk ON list_group ((CASE WHEN list_type='default' THEN NULL ELSE visitor_uid END));
Explanation:
A unique index should not care about NULL values. Therefore, make sure the index expression returns NULL for every row where list_type <> 'default'.

My two cents:
why don't you create a column only to store the unique value (maybe you can call it something like is_list_type_default) and another to store all the values. If you do this, you can put a unique constraint on the first column.

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.

whats the process to check unique value mysql

See we have one table with unique key on one field,
now whenever we are inserting any record,how mysql checking that that field value is exist in table or not?
whats the logic here?
its internally fires queries to check that that value is exist in table ? I think thats not possible.
here unique filed can be any id,email,username anything
MySQL creates index for primary and unique keys. So it checks index to see that new inserting value is unique actually. Since it is checking index, it does not hurt performance.
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.
Well it has to find the record in the index anyway when you inserting a value in order to write the data and to update all the indexes with your new value. Not much trouble to read that location and compare it to the new values.
so yes it just runs your query.

How do I create a unique combination constraint/index in MySQL? (NOT permutation)

How do I create a unique combination constraint/index in MySQL? I do not mean a permutation. The order does not matter.
For example: I have two users that I want to match up together with a linking table. The table has nothing more than two columns which are both foreign keys corresponding to the primary key on the users table.
How do I create an index that will ensure that the pair remain unique in either order?
In your application enforce that col1 < col2 - this provides a consistent order and ensures only a single linking row will ever be generated. This does not mesh well with your preconditions ("in either order"), but it sounds like it should work for your situation. I ran into a similar problem before, before project requirements changed to asymmetric user relationships (a la Twitter).
as far as i understand your question. you want to add Unique Constraint combining two columns.
so try
ALTER TABLE `tableName` ADD UNIQUE (
`first_column` ,
`second_column`
);

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.