1

I am currently working at a construction management software and I stepped into a problem (described below) when designing the schema for my database which contains four tables, for now, i.e employee, address, user and license.

The tables that created the confusion are employee and address; code provided down below.

In order to maintain the Physical integrity of my data, I did not store anything lexically derived from address, such as Address1, Address2, City, State, County etc in the table employee; since I subjectively considered that it would be better for attributes that do not uniquely identify a specific employee to make part of another table. Now my question arises:

  • Is it a good choice to use a GUID as the primary key for the address table?
  • If yes, is there any possibility that it may be a factor which prevents fast querying?

The reason why I have chosen to use a GUID as PK-indexing is that I was left with no options. EmployeeId from address does not offer me a solution since I can not have a field being PK as well as FK: see this.

CREATE TABLE employee(

    employeeId  INT
                NOT NULL
                CHECK(employeeId > 0),

    firstname   VARCHAR(20) 
                NOT NULL,

    lastname    VARCHAR(20)
                NOT NULL,

    sex         VARCHAR(1)
                NOT NULL,

    birthdate   DATE
                NOT NULL,

    addressId     VARCHAR(30),

    PRIMARY KEY(employeeId)
);

CREATE TABLE address(
    addressId   VARCHAR(30)
                NOT NULL,

    employeeId  INT,

    Address1    VARCHAR(120)
                NOT NULL,

    Address2    VARCHAR(120),

    Address3    VARCHAR(120),

    City        VARCHAR(100)
                NOT NULL,

    State       CHAR(2)
                NOT NULL,

    Country     CHAR(2)
                NOT NULL,

    PostalCode  VARCHAR(16)
               NOT NULL,

    PRIMARY KEY(addressId),

    FOREIGN KEY(employeeId) REFERENCES employee(employeeId) ON DELETE SET NULL

);

ALTER TABLE employee
ADD FOREIGN KEY(addressId)
REFERENCES address(addressId)
ON DELETE SET NULL;

I would love to know if there are any other ways to create an appropriate relationship between employee and address without using GUID. Another way would be a specified (int) value, but in that case a disadvantage would be:

  • Introducing by mistake a FK != PK which will lead to a poor relationship between the tables.

EDIT:

Some of you suggested in the comments to change "UUID" indexing to AUTO_INCREMENT but the problem for me arises when I have to insert employees from my WPF-application.

The PK addressId from address will keep increasing on its own. What am I supposed to pass into the FK then to keep the relationship tight and correct then?

Should I create a variable of type int, let's say var i = 0 and every time I insert one employee -> increase that variable by one -> assign it to the FK or?

Ryk
  • 123
  • 7
  • 1
    As an aside, varchar(1) seems like a silly idea – Strawberry Jan 28 '19 at 22:11
  • How do you feel about adding a table to put the relation between employees and addresses? f.e. with 2 FK: (Id, employeeId, AddressId). The address table could be simplified then. – LukStorms Jan 28 '19 at 22:11
  • Both your employee and address tables would have their own primary keys. Your address table would then have a foreign key that holds the primary key of the associated employee record. What’s the issue? – Martin Bean Jan 28 '19 at 22:12
  • @Strawberry why do you think that? – Ryk Jan 28 '19 at 22:12
  • 1
    Well, there's not much 'var' in 1, is there? – Strawberry Jan 28 '19 at 22:12
  • @LukStorms Could you please elaborate your idea? – Ryk Jan 28 '19 at 22:12
  • @Strawberry I define Male as 'M' and Female as 'F'. Yes...it may be a bad idea, thank you for noticing! – Ryk Jan 28 '19 at 22:13
  • @Ryk . It's 2019, consider at least 'O' for 'other'. Aside from that, why wouldn't you want to use a simple auto-incrementing mysql id? If you want GUID don't store them as strings, this is very slow and large compared to the underlying integer. Lastly, GUID is a microsoft term, the rest uses 'UUID'. – Evert Jan 28 '19 at 22:17
  • 1
    In which case Char would seem more sensible to me – Strawberry Jan 28 '19 at 22:18
  • @Evert I didn't use auto increment because you can not have two fields that auto increment in the same table. – Ryk Jan 28 '19 at 22:20
  • @Strawberry I see, you are right! :) – Ryk Jan 28 '19 at 22:20
  • Another option is to add 3 FK in the employee table. (addressId1, addressId2, addressId3). It's easier to join than by using a 3th relation table like [this](https://i.stack.imgur.com/phRSz.png) – LukStorms Jan 28 '19 at 22:23
  • @Ryk I don't see an AUTO_INCREMENT field in your address table. – Evert Jan 28 '19 at 22:29
  • @Evert so you would recommend changing from "UUID" to AUTO_INCREMENT? – Ryk Jan 28 '19 at 22:31
  • @Ryk In MySQL the 'standard thing to do' is to use an AUTO_INCREMENT primary key. Generally you need to have a good reason _not_ to use it. So if you don't have a reason against it, I would say: yes... use it ;) – Evert Jan 28 '19 at 22:32
  • @Evert Let me edit the post to make my intentions a little bit clearer. – Ryk Jan 28 '19 at 22:35
  • A couple of things: (1) Unless something changed with MySQL recently, a table can have a PK that is also an FK (though usually that means the table didn't actually need to be separate for logical reasons, perhaps performance reasons maybe. (2) The addresses table would not need two auto-increments, only one for it's own PK id. It's field referencing employee should NOT be auto incrementing. (3) I am not sure if MySQL has implemented CHECK constraints yet. – Uueerdo Jan 28 '19 at 22:37
  • (4) this seems to be an odd idea _"it would be better for attributes that do not uniquely identify a specific employee to make part of another table"_, that kind of thinking would lead to a database full of tables that are nothing but primary keys. names don't even uniquely identify employees. – Uueerdo Jan 28 '19 at 22:40
  • For what it's worth, if an employee and address is a 1:1 relationship, you only need one foreign key, not 2 – Evert Jan 28 '19 at 22:43
  • @Uueerdo What do you suggest then? I didn't say explicitly that a table can not have both PK and FK. I was implying that is not the best idea, that why I have provided that link. – Ryk Jan 28 '19 at 22:48
  • The answer in the link you suggested was actually referring to my point 4. If an address is only associated with one employee, and an employee has only one address there is usually no reason to have a separate table. – Uueerdo Jan 28 '19 at 23:07

1 Answers1

2

You'll want something like this in order to do a many-to-many association between employees and addresses (Address types will be like home, work, billing, travel, etc.). You can then create other entity tables to track associations between those entities and addresses as well. In the table employee_address, those columns will be foreign keys back to their relative tables.

As for using GUIDs vs INT for primary keys, numeric values read faster than string values on a JOIN. Depending on how large your data gets, you may need to switch from INT to BIGINT years down the road.

Also, give these people some space to enter their names. 20 characters is way too short, especially for last names.

employee
--------
employee_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(255) NOT NULL, 
lastname VARCAHR(255) NOT NULL,
gender BIT NOT NULL,
birthdate DATE NOT NULL

address
---------
address_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
address1 VARCHAR(255),
address2 VARCHAR(255),
address3 VARCHAR(255),
city VARCHAR(255),
state CHAR(2),
country CHAR(2)

address_type
--------------
address_type_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
address_type VARCHAR(255)

employee_address
-----------------
employee_address_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
employee_id INT,
address_id INT,
address_type_id INT
Adrian J. Moreno
  • 14,350
  • 1
  • 37
  • 44
  • I am sorry if the question may look silly but why would I need the address_type? What does it stand for? Could you elaborate a little bit more, please? PS: The approach as a whole looks way better than mine though. – Ryk Jan 28 '19 at 23:14
  • It's in the answer, but address types allow you to specify just that: Is this a home address, a work address, used for billing, used to calculate travel costs? You said you're building "construction management software", you'll also need things like a "work site address", "business address". – Adrian J. Moreno Jan 28 '19 at 23:37
  • That is totally right, I didn't realize you paid attention to that information too. The answer helped me a lot, I appreciate. – Ryk Jan 28 '19 at 23:39