简体   繁体   中英

MySQL Compound Primary Key Column-Order-Insensitivity

For compound keys in MySQL, does the order of the columns matter for insuring the uniqueness of the rows?

Eg

CREATE TABLE test (
    A  INT NOT NULL,
    B  INT NOT NULL,
    PRIMARY KEY (A, B)
);

Now, assuming I already have a row that contains the values A = 1, B = 2, will MySQL refuse to insert a row with A = 2, B = 1?

I ask this because I need a solution that uses a compound key & ignores the order of the values.

不,唯一性无关紧要,仅对排序和访问时间很重要

The ordering in an index matters. As a reminder for why the order matters, consider what happens if the types are incompatible -- say date and varchar(255) . The values are not interchangeable.

If you want uniqueness for both values, then you are going to need to add a trigger. The trigger can probably implement a much simpler condition, which is the requirement that A be less than B . This, in combination with the primary key will guarantee uniques across the two values. You can express this constraint in MySQL:

CONSTRAINT CHECK (A < B)

But, alas, MySQL will parse the code, but not execute the check. Instead, you can add before update and before insert triggers to put the smallest value in A . Here is an example:

CREATE TRIGGER table_beforeinsert BEFORE INSERT ON table
     FOR EACH ROW 
     BEGIN
         declare xx int;
         if (NEW.A > NEW.B) then
             set xx := NEW.A;
             set NEW.A = NEW.B;
             set NEW.B = xx;
         endif;
     END

Haha, no! The key is compound of the attributes.
Excuse me for being amused, it's just that you know that the values of
your attributes are different A : 1 != 2 and B: 2 != 1.
Just imagine the rows in the table.
A|B
1|2
2|1

Imagine it as eg a string concatation: "1:2" whilst "2:1".
Obviously these strings are not equal.
Internally the representation of a compound primary key will be less trivial, of course,
propably based on a hash function, stored into a temporary memory region for look ups
which is divided into
range based pages.

So what is important is not the ordering of the attributes in the key but the values for
the corresponding columns.
Actually the process of determining which attributes can be used best for a compound
primary key is a very interesting one.
So you should understand the process clearly otherwise you may wonder why you experience
data inconsistency.
Take as an example a person's table:
Name, FirstName, Birthdate, Street, City, Country, State, zip
Actually none of the attributes satisfies the condition of uniquely identifying a person.
Neither does Name and Firstname.
Well, so Name and Firstname and Birthdate as well as City is not too bad, but take a look
at how many people named Peter Smith live in London (may it be located in GB or in
Ontario, Kanada).
The process of determinating the candidate key is in fact the the process of defining functional dependencies between attributes.
Basically the idea is:
If I know a Persons lastname, do I know his first name.
If I know a Persons lastname and his first name, do I know in which city he lives?
and so on.
This function dependencies are written as:
City, Country, State --> zip // meaning : when I know a persons city, country and state I know his Zip.
(and the other way round, of course) The attributes that don't appear on the right side of the dependency list, must be part of every candiate key.
If every attribute else is determined by this attributes, you are done. You got your
compound primary key.
If not:
Then the process of finding the optimal candiate key is just the steps of using first
a key made of all attributes in the table.
Then remove the attributes that depend. List all candiate keys and repeat.
Then see similarities (which candidate keys are contained in other candidate keys, this is called reduction).
So you will get to the optimal compound primary key for your table.
As an example for the first case:
Attributes
A Name, B LastName, C City, D State, E zip (internationally)
E --> C // international zips have a form of eg GB-W11 2BQ
E --> D
So the first candidate would be:
A, B, E (as they don't appear on the right side).
Is every attribute else depending? Yes, there are only C and D left.And they depend on E
You're done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM