I'm confused what a schema should be implemented in a following case:
I have two core tables user and company and a set of 'inherited'(in terms of ORM) tables like user_type_1, user_type2 that extend user table with an own unique set of fields. And the same for company_type_1, company_type_2 tables that extend company table with an own unique set of fields.
Also I have a address table. Every User and Company in a system can have own address.
My initial idea was to add address_id FK to address(id) PK to root user and company tables. This way every User or Company in a system can be associated with own address.
My colleague proposed another database schema design where user_id and company_id FKs have to be added to address table.
I'm really confused with this proposal right now. Could you please explain or this design can take a place ?
If you add address_id to the user and company tables, you're adding functional dependencies user_id -> address_id and company_id -> address_id. This would mean that each user or company can be associated with a single address, but each address can potentially be associated with multiple users or companies (unless you add a constraint to prevent that).
Your colleague's proposal to add user_id and company_id to the address table adds functional dependencies address_id -> user_id and address_id -> company_id meaning each address can be associated with one user, one company or both, but each user or company can potentially be associated with multiple addresses (unless you add a constraint to prevent that).
Between the two options you listed, there's a third - separate tables for the associations, e.g. user_addresses (user_id FK, address_id FK) and company_addresses (company_id FK, address_id FK). This can handle any cardinality (one-to-one/one-to-many/many-to-one/many-to-many) depending on the PK (address_id, user_id/company_id or both) and possible unique constraints.
Which design is correct depends on your requirements.
Related
Above is my normalised database structure for my app. I am going to store Users, and their favorited Images. Images might be alone (hosted on reddit) or in albums (hosted on imgur), and they always have a title.
Question is - is the database set up correctly? I have this feeling that i have something wrong with ImageAlbum and Image table relationship.
EDIT: This might work?
The main issue with the original design is that the intended relationship between a user and an image would not be possible, as the two tables are not connected.
As a general rule of thumb, if there's a 1-1 or a 1-many relationship between tables, you can rely on constraints. I.e. 1 customer can place many orders. You have a Customer table with a CustomerID PK column, and an Order table containing an OrderID PK column, and a Foreign Key constraint to the CustomerID column of the Customer table. That establishes the relationship, and ensures that you cannot place an order if you are not a customer.
An order typically consists of one or more products, and a product typically can be purchases in multiple orders. In cases like this, you cannot set up this relationship the same way. A common workaround for that is to do so using an intermediate table that establishes the many-to-many relationship.
So building on the earlier tables, we also have a Product table, with a ProductID column as a PK. To set up the relationship between Order and Product, you would then credit an OrderProduct table, with FKs pointing to the OrderID and ProductID in question (and probably also something indicating quantity of products for this particular order, and perhaps something like a FK to a Discount or campaign table, and whatnot).
So in your scenario, I would establish the relationship between Image and User using a similar approach, and simply adding a UserImage table to allow for the many-to-many relationship. You then also add an AlbumImage table to determine the many-to-many relationship between images and albums.
As indicated in the comments, there's no need to have an AlbumTitle table, really. It would naturally belong to the Album table. The ImageTitle would belong in the UserImage table, because every user can add their own title to an image.
Suppose there is a table keeping info about Vendors and Customers in one table named Partners (since one partner can be vendor at one point of time and customer at other).
Partners table have usual stuff: company name, short name, address, city, country. Now, for domestic partners there is DomesticVatNumber and for non-domestic there is InternationalVatNumber. Usually, vat number would be perfect candidate for primary key but the problem here is that not all domestic partners have InternationalVatNumber and international ones dont have DomesticVatNumber.
I am trying to see best ways to design this in db. Is surrogate key the only option in this case or should i maybe reconsider having domestic and international partners in same table? Should i maybe split them into 2 tables: DomesticPartners (which always have DomesticVatNumber) and InternationalPartners (which always have InternationalVatNumber) and then put primary key on DomesticVat and InternationalVat columns respectively?
What are pros/cons of each approach?
Personally, I would never make a primary key out of something assigned by an external party, nor would I use a value that the user would ever see. I would always use a meaningless key (either an identity column or a unique identifier).
Given what you are saying, I wouldn't split them into separate tables since you would then have to either have any table that referenced your partner table in a foreign key would either have to have two nullable columns setup to do this or have one column but no foreign key relationship (shudder...).
The best option is to have one table, have the domestic and international VAT numbers as separate fields in the table but not a primary key. Since they will both be nullable, you would have limited options for a unique constraint on them.
Just my 2 cents
As your business grows, your systems get more complex, and it makes more sense to have one table. An example can be an ENTITIES table which stores everyone and everything, including vendors and customers. This can include individuals, groups and businesses, clients and staff, etc. Later on you will be glad you did it this way, because it reduces the number of complex joins you are going to have with multiple tables. You can use ENTITY_NO as a surrogate key and ENTITY_TYPE to differentiate entities. VAT number fields can be indexed separately and made nullable.
This is my tables definition :
User
Id
Name
IsAdmin
Ticket
Id
User_id
Admin_id
My admins buy tickets for the users, I have Admin and User in a Table but i have to get two foreign keys from User table in Ticket table.
Is this solution standard and normal, or cause to low performance?
Yes, completely standard. Semantically, the ticket is defined by the user it is for, and the admin who purchased it, so it sounds like your design reflects reality (which is a good thing).
This is more or less standard, though it is somewhat flawed, as there’s nothing to prevent an Admin_Id from being set to a "user" id. (This could be enforced programmatically, though ultimately it might require a trigger.)
Performance-wise, it only really matters when Tickets are created (have to look validate the user ids through a lookup in the User table) or updated (ditto), or when Users are deleted (have to make sure user id is not in use in either column in the Ticket table). The questions become: how big are these tables, how often are any of these actions taken, and (if relevant) are there indexes to support these queries?
Purists would normalize your structures like so:
User
Id -- Primary key. To avoid confusion, this couldbe set to User_id
Name
Admin
Id -- Primary key, with foreign key to User.Id To avoid confusion, this could be set to Admin_id
Ticket
Id -- To avoid confusion, this could be set to Ticket_id
User_id -- with foreign key to User.Id
Admin_id -- with foreign key to Admin.Id
(Admin is a “subtype” of User.)
I have two tables: Companies and Employees.
I also have a relation table Employs which contains the foreign keys company_id, employee_id as a composite primary key. Note: employees can work at multiple companies.
I would like to have another table EmployeeSchedules which simply contains schedules (company_id:integer,employee_id:integer,start_time:datetime, end_time:datetime) for employees working at a company. This will end up being displayed in a calendar widget of some sort.
However, with this design I would have to verify at the application level that the employee actually works at the company before adding a schedule.
I was wondering if there would be a better way to represent this at the database level or just stick with verifying at the application level? For example, if there was a way to link the EmployeeSchedules pkey (company_id,employee_id) with the Employs pkey (company_id, employee_id). Any other design recommendations are welcome!
I would re-define the schema, and add another table:
Person(id, name)
Company(id);
Employee(id, companyId, personId);
Schedules(id, employeeId, startTime, endTime);
That means a an employee record can only be bound to one company. A person can have multiple employee records however. All the "id" columns are unique, and are the primary key of the table. "companyId" refers to the primary key of the company table and so on.
We have multiple offices, and within each office there are multiple departments (some departments have employees in multiple offices). We have two existing systems that identify employees in different ways: in one, employees are identified by IDA; in the other employees are identified by IDB.
In the cases where an employee is identified by an IDA, we need to identify that employee's supervisor, if any, in SUPERVISOR_IDA.
My table looks like this:
IDA
IDB
SUPERVISOR_IDA
OFFICE
DEPARTMENT
Employees could have positions in more than one office, or in more than one department, so the same IDA or IDB could exist more than once, but with a different office, department or both.
The problem is that IDA could be null (and if so, then IDB is not null) or IDB could be null (and if so, then IDA is not null), or both could be present.
I'm trying to set up unique and/or primary keys and constraints to ensure the integrity of the database.
So I created a unique key on (IDA, IDB, OFFICE, DEPARTMENT).
Here's my problem:
I need to ensure that employees reference their supervisors. I wanted to have a self-referencing foreign key so that removal of supervisors would not leave orphan employee records who have a non-null SUPERVISOR_IDA. But since I was required to include IDB in my unique key on this table, if I create this foreign key I am required to include IDB as such:
local PARENT_IDA -> reference IDA
local OFFICE -> reference OFFICE
local DEPARTMENT -> reference DEPARTMENT
**local IDB -> reference IDB**
This is a problem because the employee IDB should NOT be the same as the supervisor IDB.
I know it seems like I'm trying to do too many things in one table perhaps, but in reality my domain is quite difficult to describe and so I created the employee/office/department as an example to illustrate my problems. I really cannot split IDA and IDB into separate tables, as they are intertwined in some problematic ways and the presence of one, the other, or both, has some important meaning that cannot be separated.
At first I wanted to set up a unique key on (IDA, OFFICE, DEPARTMENT) in addition to the aforementioned unique key, but unlike with unique keys that consist of a single column, composite unique keys will treat (null, 'A') and (null, 'A') as duplicates instead of allowing the null column to avoid violation of the uniqueness constraint.
I think the problem is with the model. The table should have a primary key (and if IDA or IDB can be null then they are not PK columns) and the foreign key should reference the PK.
I think you are trying to use an FK against a unique index to enforce a bunch of cross-row validation rules in the data model, such as "an employee can only be supervised by someone in the same office and department" and "an IDA employee can only be supervised by another IDA employee".
In practice those are very hard to enforce when you consider multiple people potentially updating different columns on different rows at the same time.
That said, you could try adding columns DEPT_IDA and OFFICE_IDA and using triggers to set them from DEPT and OFFICE only when IDA is set. Then create the UK on those columns
I think your data model is wrong. You should have only one EMPLOYEE record per employee. Then you can have unique keys on each of IDA and IDB.
Because employees work at multiple offices then you need a table to represent that; POSTS would be an intersection table between OFFICES and EMPLOYEES.
The point being that SUPERVISOR_IDA and SUPERVISOR_IDB are properties of POSTS, and as such you can enforce a foreign key between those columns and the EMPLOYEES table. Use check constraints to ensure that if the POSTS record is identified by an EMPLOYEE_IDA the SUPERVISOR_IDA is populated and ditto for EMPLOYEE_IDB.
I am not sure if this works in Oracle but in SQL Server I would create a trigger that on the SUPERVISORS table that fires on UPDATE and DELETE. The trigger would query the EMPLOYEES Table for any records where SUPERVISORS.SUPERVISOR_IDA = EMPLOYEES.SUPERVISOR_IDA. If any records where found, it would roll back the transaction.
I found this link outlines what you need to do.
http://www.techonthenet.com/oracle/triggers/before_delete.php