Scenario: I have to create a database which has to contain 3 different tables holding information about people. Lets call them Members, Non_Members and Employees. Among the other information they may share , one is the telephone number. The phone numbers are unique, each in its respective table.
My problem: I want to make sure the phone number is always unique among these 3 tables. Is there a way to create a validation rule for that ? If not and I need to redesign the database, which would be the recommended way to do it.
Additional info: While the 3 tables hold the same information (Name , address etc.) its not required always required to fill them. So I am not sure if a generic table named Persons would work for my case.
Some ideas: I was wondering if and how I can use a query as a validation rule (that would make things easier). If I would end up creating a table called Phone numbers , how would the relations between the 4 tables would work in order to ensure that each of the 3 tables has a phone number.
ERD
I assume you are talking about a relational database.
I would go for a single person table with a "type" column (member, non_member, ...). That is much more flexible in the long run. It's easy to add new "person types" - what if you later want a "guest" type?
You would need to define as nullable to cater for the "not all information is required" part.
With just a single table, it's easy to make the phone number unique.
If you do need to make it unique across different tables, you need to put the phone numbers in their own table (where the number is unique) and the references that phone_number table from the other tables.
Edit
Here is an example of creating such a phone_number table:
create table phone_number
(
id integer primary key,
phone varchar(100) not null unique
);
create table member
(
id integer primary key,
name varchar(100),
... other columns
phone_number_id integer references phone_number
);
The tables non_member and employee would have the same structure (which is a strong sign that they should be a single entity)
Edit 2 (2016-01-08 20:12)
As sqlvogel correctly pointed out, putting the phone numbers into a single table doesn't prevent a phone number to be used by more than one person (I misunderstood the requirement so that no phone number should be stored more than once)
Related
Using Java and Oracle.
We need to update changes in Email, UserID of employee to third party.
Actual table is Employee and intermediate table we keep which we will use for comparison of changes before sending to third party.
Following are database designs coming in mind for intermediate table:
Only Single table:
EmployeeiD|Value|Type|UpdateDate
Value is userid or email, type will be 'email' or 'userid'. Update date is kept so to figure out that which of email or userid was different and update to third party.
Multiple Table:
Employee_EmailID
EmpId|EmailID|Updatedate
Employee_UserID
EmpId|UserID|Updatedate
Java flow will be:
Pick employee from actual table.
Pick employee from above intermediate table.
Compare differences. Update difference to third party.
Update above table with updated value and last update date.
Which one is consider as best way, single table approach or multiple table or is there any standard way to implement the same? There are 10,000 Employees in system.
Intermediate table is just storing Delta records i.e Records transferred to third party so that it can be compared next day.
Good database design has separate tables for different concepts. Using the same database column to hold different types of data will lead to code which is harder to understand, prone to data corruption and less performative.
You may think it's only two tables and a few tens of thousands of rows, so does it matter? But that is only your current requirement. What you choose now will set the template for what happens when (say) you need to add telephone numbers to the process.
Now in future if we get 5 more entities to update
Do you mean "entities", like say Customers rather than Employees? Or do you really mean "attributes" as in my example of Employee Telephone Number?
Generally speaking we have a separate table for distinct entities, and all the attributes of that entity are grouped at the same cardinality. To take your example, I would expect an Employee to have one UserID and one Email Address so I would design the table like this:
Employee_audit
EmpId|UserID|EmailID|Updatedate
That is, I have one record which stores the complete state of the Employee record at the Updatedate.
If we add a new entity, Customers then we have a new table. Simple. But a new attribute like Employee Phone Number offers a choice, because an employee can have more than one: work landline, mobile, fax, home, etc. So we could represent this in three ways: a child table with a type column, multiple child tables for each type, or as distinct columns on the Employee record.
For the main Employee table I would choose the separate table (or tables, depending on whether I'm shooting for 6NF). But for an audit table I would choose one record per Employee and pivot the phone numbers like this:
Employee_audit
EmpId|UserID|EmailID|Landline|Mobile|Fax|Home|Updatedate
The one thing I would never do is have a single table with type and value columns. It seems attractive because it means we could track additional entities without any further DDL. But in fact it becomes harder to re-assemble the complete state of an Employee at any given time with each attribute we add. Also it means the auditing process itself is more complicated (because it needs to determine which attributes have changed and whether it needs to audit the change) and more expensive (because changing three attributes on the same record entails inserting three audit records).
How should I decide whether to use a nested table or a reference?
For example:
We have an airline and a flights table:
CREATE TABLE airline OF airline_ty(
token VARCHAR2(8),
description VARCHAR2(20)
)
CREATE TABLE flights OF flights_ty(
flightNumber NUMBER(10)
securityLevel VARCHAR2(10)
)
Should I know make a reference in airline (flights REF flights_ty) or go for a nested table?
It depends on the requirements for usage of the data. In your example with airlines and flights a flight should have a foreign key to its airline. The main table is flights and airlines is a codebook.
An example case where a nested table would be a good choice:
A customer in a core banking application has several phone numbers, email addresses etc. You need to hold this data for a customer, but you do not evaluate it (all customers with this email etc.), you just display it together with other customer detail. You cannot have an extra table for each one to many property, because you have much more interesting data, like accounts, loans, credit cards, account statements, behavior score cards etc.
You have always take into account, what will be the redundancy, reuse, importance, property vs. entity, aggregation vs. composition...
I am trying to implement an entity relation for a hospital oracle database system.
I am rather confused if I should seperate the table below or merge them into 1.
- Supply
ItemNo (PK) , Name, ItemDescription, QuantityInStock, BackOrderLevel, CostPerUnit
- PharmaceuticalSupply
DrugNo (PK) , Dosage, MethodOfAdmin
Basically in my ERD, I pointed PharmaceuticalSupply to Supply as a subset which inherits the attribute but also have additional attributes. Am I wrong in doing that?
Ultimately, this is a design decision that has no right or wrong answer, but keeping them separate can be helpful. For example, there are many types of supplies that are not pharmaceutical. If you merge the tables, you make it possible to enter data that has no real meaning. For example, you can't have a dosage of bandages. The separate table makes it clear that dosage only applies to pharmaceuticals.
Note that there are a few variations on how to manage the PKs and FKs in PharmaceuticalSupply. It could have both an ItemNo and a DrugNo, where ItemNo is a foreign key. In that case, either one could be the primary key, but if DrugNo is the primary key, then ItemNo probably needs to be a unique index. However, unless DrugNo is needed due to some custom format, it might work well to simply use ItemNo as both PK and FK and completely eliminate DrugNo. This results in a "specialization" as the relational database world likes to refer to it.
It depends on your population. It it's a subset, to reduce redundancy add a foreign key to Supply. That way you'll be able to build a join that list all data.
I would still introduce a DrugNo key for indexing. Can an item number appear more than once in the PharmaceuticalSupply table ? If your do then your definitely need the DrugNo key.
PharmaceuticalSupply
DrugNo (PK) , ItemNo (FK), Dosage, MethodOfAdmin
I have an app that houses product data via a Product model and table. Each product has specific state availability (multiple states) that I will need to filter and/or search by in the future. I am hoping to find someone who can tell me the most efficient way to store this data. As I see it, I have two options.
The first is to simply create 50 columns in my table, titled with each state name and containing a boolean value. I can then simply filter by = "avail in California" if product.ca. While this certainly works, it seems a bit cumbersome, especially when searching for multiple state availability.
The second option would be to simply have one column("states") that stores an array of available states and then filter by = "avail in California" if product.states.include? "CA". This seems like a better solution for two reasons. The first, it just allows for a cleaner DB table. Second, and more important, I can allow my user to search by simply saving the user's input as a variable(user_input) and then = "avail in California" if product.states.include? user_input. This solution does call for a little more work up front however when saving the product in the DB, since I won't be able to simply check off a boolean value.
I think option two makes the most sense, but am hoping for some advice as to why or why not. I have found a few similar questions, but they do not seem to explain which solution would be better, just how to accomplish each.
What should I do?
You should normalize unless you have a really good reason not to, and I don't see one in your overview.
To normalize, you should have the following tables:
product table, one record per product
state table, one record per state
product_state table, one entry for every product that is in a state
The product_state schema looks like this:
(product_state_id PK, product_id FK, state_id FK)
UNIQUE INDEX(product_id,state_id);
This allows you to have a product in zero or more states.
I assume that since you’re selling products, you will be charging taxes. There are different taxes by state, county, city. There are country taxes in some countries too.
So you need to abstract these entities into a common parent, usually called GeopoliticalArea, so that you can point a single foreign key (from, say, a tax rates table) at any subtype.
create table geopolitical_area (
id bigint primary key,
type text not null
);
create table country (
id bigint primary key references geopolitical_area(id),
name text not null unique
);
-- represents states/provinces:
create table region (
id bigint primary key references geopolitical_area(id),
name text not null,
country_id bigint references country(id),
unique (name, country_id)
);
insert into geopolitical_area values
(1, 'Country'),
(2, 'Region');
insert into country values
(1, 'United States of America');
insert into region values
(2, 'Alabama', 1);
I have to add some security for a C#/.NET WinForms/Desktop application. I am using Oracle DB back-end.
The tables are simple: User (ID,Name), Role(ID,Role), UserRole(UserID,RoleID).
I am using the windows account name to populate User table. Role table will for now just be simply 'Admin','SuperUser','BasicUser'...
Since no two people could ever possible have the same windows account name... even when I do not control these name management (netops does, hence why I want to use windows accounts so I don't have to manage it ;)). For Role table, I should again never have dupe value - I control the input, there will only be 3 (tactical app going away within year). UserRole is a join table to represent the Many-To-Many relationships of users and roles, so no surragate key is justified.
Simple question - Why bother with 'ID' (int) in the User and Role table? Any point or advantage here? Is this one of those 'I've always done it this way' type things? Or have I just not done this in awhile and forget the reason?
Names change - primary key values must not. Abigail Smith becomes Abigail Jones and the username changes but a surrogate key protects against having to cascade those changes everywhere.
If you are using a surrogate key but there is a column or combination of columns which should be unique, then enforce that using a unique index. There's a good chance you'll want indexes on your user.name and role.role columns anyway, and a unique index is more space efficient and supplies useful metadata to the optimizer. If you have a surrogate key but don't have another combination of columns that uniquely identify a row then think again whether you have your entity definition right.
One caution. Especially for very narrow tables with few access paths, you may use an index-organized table. Oracle will only allow an index organized table on the primary key, but does allow foreign keys against a unique set of columns (if it is enforced by a unique constraint, not simply a unique index).
It is possible that you'll end up with a table where a unique ID is enforced through a unique index and treated as PK by an ORM and used as the parent for foreign key relationships, but the primary key (as defined in the DB) is the rolename/username/whatever because you want that as the driver for an index-organised table.
A surrogate key is not required on intersection tables, but here are a few reasons to do so:
Consistency: If every table has a single artificial key, you always know the key name when you know the table name.
Ease Of Use: Less typing — one key means ON and WHERE clauses are shorter and thus less error-prone.
Interoperability: Some ORMs only work well with tables with a single primary key column.