简体   繁体   中英

MySQL - Undirected graph representation

I have the following problem, and I'm wondering if it is possible to solve it in native SQL. Assume, that I have an undirected graph which must not contain more than one edge between 2 nodes.

I would like to represent it in a database table, which has eg the following scheme and content:

    ID|Node1|Node2|
    ---------------
    1 | A   | B   |
    2 | B   | C   |
    3 | D   | E   |
    4 | F   | D   |

I would like to set up a constraint in database level in MySQL which prevents, that I could add the following record to the table above

    5 | B   | A   |

Does someone know any solution for this in MySQL ?

Thanks in advance!

If MySQL supported CHECK constraints, you could simply:

CREATE TABLE Edge (
    Node1 VARCHAR(50),
    Node2 VARCHAR(50),
    Direction ENUM('forward', 'backward'),
    PRIMARY KEY (Node1, Node2),
    INDEX (Node1, Node2),
    CHECK (Node1 <= Node2) -- Use < if you don't want self-referencing.
);

INSERT INTO Edge VALUES
    ('A', 'B', 'forward'),
    ('B', 'C', 'forward'),
    ('D', 'E', 'forward'),
    ('D', 'F', 'backward');

[SQL Fiddle]

And then, you get the PRIMARY KEY violation if you try:

INSERT INTO Edge VALUES ('A', 'B', 'backward');

Unfortunately, MySQL will allow...

INSERT INTO Edge VALUES ('B', 'A', 'forward');

...despite the CHECK constraint, so you'll have to protect against this case in triggers or application logic.

Are you OK with 'sorting' the node names? That is, Node1 is guaranteed to be less than Node2 in value.

For example, the pair (C, A) is guaranteed to be written as: (A, C)

Your code should take care of this; you can use min/max to handle it.

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