Entity Framework Database Design Foreign Key and Table linking - entity-framework

Ok I have a master table which can be designed in two different ways, and I'm unsure of the best approach. I am doing model first programming in regards to setting up the database.
I have 5 tables so far.
Master table
Departments
Functions
Processes
Procedures
Which is a better way to handle the design?
Idea #1:
Master Table
masterId, departmentID, functionID, processID, procedureID, user1, date
Should I make it this way and then provide a FK from master to the departments table, functions table, processess table and procedures table?
Idea #2
Master Table
MasterID, departmentID, user1, date
This table will link to Departments table, which will then link to functions, which will link to processes which will link to procedures.
The master table will have a complete list of everything.
A department can have many functions.
a function can have many processes.
a process can have many procedures.
Which of the ways is best or am I just doing it completely wrong and someone can tell me thee or close to thee best way to create this diagram of tables and linking structure?

If you have the following criteria,
A master can have many departments.
a department can have many functions.
a function can have many processes.
a process can have many procedures.
Then you must use your second design idea. You only have one department, one function, one process, and one procedure key in your first design idea.
Master
------
Master ID
User
Date
...
Department
----------
Department ID
Master ID
...
Function
--------
Function ID
Department ID
...
and so on.
The primary key of each table is an auto incrementing integer or long.
The foreign keys are identified by name.

Related

PostgreSQL: Table that points to other Tables?

Just getting started in PostgreSQL and wanted to ask some questions.
Suppose that I have a table of Vendors. Each Vendors has an attribute called Sales Record, which is a time series data about their sales. For each Vendors, I want to be one associated Sales Record Table that has the timeseries sales data for that specific vendor.
How might I want to code that?
You shouldn't have a table per vendor.
Rather, create one big table for all. The table contains a column like vendor_id that is a foreign key to vendors and identifies to which vendor a record belongs.
If you create an index on vendor_id, searching the big table for the data of a vendor will be efficient.

How to link one staff to multiple service she can offer using PostgreSQL?

I am trying to understand how I can possibly link 1 staff row to all the services that staff can offer.
- Staff can offer multiple services.
- Services are assigned to multiple staff.
I know about foreign key but from what I know it can only link to 1 row in a foreign table. I tried to search for an array that could contain multiple foreign keys and it doesn't exists.
How can I possibly assign example:
-staff1 provides: service1, service3.
and -staff 2 provides: service2, service3.
How can I do it in a good architecture?
thank you so much for your time and help it is very appreciated!
You need a many-to-many relationship between your staff and service tables. Here's how you do that.
Create a so-called join table. It will have this structure.
CREATE TABLE staff_service (
service_id INT NOT NULL,
staff_id INT NOT NULL,
PRIMARY KEY (service_id, staff_id),
UNIQUE INDEX staff_service (staff_id, service_id)
);
When there's a row in this table, it means that staff member provides that service. So, when a staff member starts to offer a service, INSERT a row in the table. When a staff member stops offering the service, DELETE the row.
There are two indexes in my suggested table definition. That's so lookups in both directions can take advantage of indexes.
This is the canonical way of using SQL-based RDBMSs to handle many-to-many relationships.

Postgres table partitioning with star schema

I have a schema with one table with the majority of data, customer, and three other tables with foreign key references to customer.entry_id which is a BIGSERIAL field. The three other tables are called location, devices and urls where we store various data related to a specific entry in the customer table.
I want to partition the customer table into monthly child tables, and have that part worked out; customer will stay as-is, each month will have a table customer_YYYY_MM that inherits from the master table with the right CHECK constraint and indexes will be created on each individual child table. Data will be moved to the correct child tables while the master table stays empty.
My question is about the other three tables, as I want to partition them as well. However, they have no date information (at all), only the reference to the primary key from the master table. How can I setup the constraints on these tables? Is it even meaningful or possible without date information?
My application logic knows where to insert all the data (it's fairly trivial), but I expect to be able to do simple SELECT queries without specifying which child tables to get it from. So this should work as you would expect from non-partitioned tables:
SELECT l.*
FROM customer c
JOIN location l USING entry_id
WHERE c.date_field > '2015-01-01'
I would partition them by the reference key. The foreign key is used in join conditions and is not usually subject to change so it fulfills the following important points:
Partition by the information that is used mostly in the WHERE clauses of the queries or other parts where partitioning can be used to filter out tables that don't need to be scanned. As one guide puts it:
The objective when defining partitions should be to allow as many queries as possible to fetch data from as few partitions as possible - ideally one.
Partition by information that is not going to be changed so that rows don't constantly need to be thrown from one subtable to another
This all depends of the size of the tables too of course. If the sizes stay small then there is no need to partition.
Read more about partitioning here.
Use views:
create view customer as
select * from customer_jan_15 union all
select * from customer_feb_15 union all
select * from customer_mar_15;
create view location as
select * from location_jan_15 union all
select * from location_feb_15 union all
select * from location_mar_15;

How to model a database where a row in a table can belong to one of many other tables

I'm trying to workout the best database design for the following :
1) I have two (or more) tables in the database. "Sports", "Teams", "Leagues", etc..
2) Each of these tables can have a one to many relationship with another table in this case "Feeds"
The idea being that various database entities can each have a list of associated "Feeds"
It seems wrong to me to have multiple foreign key columns on the "Feeds" table, one for each of the tables (Sport, League, etc..), so my question is how best to model this?
It's worth mentioning that each feed can only belong to one of the other tables. A feed can't be associated with a "Sport" and a "League"
I've considered the following :
1) Add an additional column to each of the "Sport" "League" etc.. tables with a GUID.
2) Add another column to the "Feeds" table also with a GUID and populate this with the GUID from my other table, then query on this.
This would allow me to have multiple tables referencing the same column of the "Feeds" table but is this any better than having multiple nullable foreign keys, one for each table?
It is not a bad idea to have a foreign key pointing to Feeds in several tables. Foreign keys can be used to handle the 1:n relation (one-to-many).
It seems wrong to me to have multiple foreign key columns on the
"Feeds" table, one for each of the tables (Sport, League, etc..), so
my question is how best to model this?
Why do you think it is not a good practice, what would be the downside of this design?

How to maintain record history on table with one-to-many relationships?

I have a "services" table for detailing services that we provide. Among the data that needs recording are several small one-to-many relationships (all with a foreign key constraint to the service_id) such as:
service_owners -- user_ids responsible for delivery of service
service_tags -- e.g. IT, Records Management, Finance
customer_categories -- ENUM value
provider_categories -- ENUM value
software_used -- self-explanatory
The problem I have is that I want to keep a history of updates to a service, for which I'm using an update trigger on the table, that performs an insert into a history table matching the original columns. However, if a normalized approach to the above data is used, with separate tables and foreign keys for each one-to-many relationship, any update on these tables will not be recognised in the history of the service.
Does anyone have any suggestions? It seems like I need to store child keys in the service table to maintain the integrity of the service history. Is a delimited text field a valid approach here or, as I am using postgreSQL, perhaps arrays are also a valid option? These feel somewhat dirty though!
Thanks.
If your table is:
create table T (
ix int identity primary key,
val nvarchar(50)
)
And your history table is:
create table THistory (
ix int identity primary key,
val nvarchar(50),
updateType char(1), -- C=Create, U=Update or D=Delete
updateTime datetime,
updateUsername sysname
)
Then you just need to put an update trigger on all tables of interest. You can then find out what the state of any/all of the tables were at any point in history, to determine what the relationships were at that time.
I'd avoid using arrays in any database whenever possible.
I don't like updates for the exact reason you are saying here...you lose information as it's over written. My answer is quite simple...don't update. Not sure if you're at a point where this can be implemented...but if you can I'd recommend using the main table itself to store historical (no need for a second set of history tables).
Add a column to your main header table called 'active'. This can be a character or a bit (0 is off and 1 is on). Then it's a bit of trigger magic...when an update is preformed, you insert a row into the table identical to the record being over-written with a status of '0' (or inactive) and then update the existing row (this process keeps the ID column on the active record the same, the newly inserted record is the inactive one with a new ID).
This way no data is ever lost (admittedly you are storing quite a few rows...) and the history can easily be viewed with a select where active = 0.
The pain here is if you are working on something already implemented...every existing query that hits this table will need to be updated to include a check for the active column. Makes this solution very easy to implement if you are designing a new system, but a pain if it's a long standing application. Unfortunately existing reports will include both off and on records (without throwing an error) until you can modify the where clause