I want to build the following defect detection system in SQL Server. The interface will be built using ASP.NET . but currently i am struggled on how to build the Database tables the relation between these tables.
the system allow to create a report >> select the report type,Equipment ID & other info >> select the wanted categories (by choosing Y or N) >> and for the selected category >> select the defect details and enter the comments..
I came out with this schema (Table names & Columns):-
Equipment
ID
Name
Operator
ID
Name
Report Type
ID
Name
Report
ID
Operator ID (FK to Operator),
Name
Equipment ID (FK to Equipment)
Type ID (FK to Report Type)
Date/Time
Comments
ReportCategory
ID
Name
Part
ID
Name
ReportCategory
Report ID (FK to Reports) -->PK
Category ID (FK to Category) --> PK
Yes/no
DefectDetailesLookup
Part ID (FK to Part) ---> PK
Cateogry ID (FK to Cateogry) ---> PK
ReportDefectDetails
ReportID (FK to Report) --> PK
Category ID (FK to Category) --> PK
Part ID (FK to Part)-->PK
Comment
Yes/No
so are the schema valid? or i am missing something? thanks
It would work.
There are a few things worth giving a thought for future changeability: Without fully understanding your applications domain: Give composite PKs a second thought. It is not necessarily a bad practise to use them, but if you use them make sure they are an integral part to the Entities Identity. And if you are not sure, I'd recommend to remove them and rather use an own Identity column for your Entity. Otherwise you are bound to having i.e. a Category for every ReportDefectDetail.
If you are not dependent on an existing database and assuming you already have your repository classes set up, give ef core and code-first a try. Also DDD (domain driven design) is a worthy read. Modern db models are mostly code driven/domain driven. The time of dbs dictating how the code should be written are gone.
Aside from that:
little typo here: DefectDetail_e_sLookup
ReportCategory => exists two times. I guess the upper one is just Category
give your yes/no columns meaningful names, like isDisplayed
-- Defect DEF named DEF_NME, with comment DEF_CMT exists.
--
defect {DEF, DEF_NME, DEF_CMT}
PK {DEF}
AK {DEF_NME}
-- Defect category CAT named CAT_NME exists.
--
dcat {CAT, CAT_NME}
PK {CAT}
AK {CAT_NME}
-- Defect DEF is in defect category CAT.
--
defect_category {DEF, CAT}
PK {DEF, CAT}
FK1 {DEF} REFERENCES defect {DEF}
FK2 {CAT} REFERENCES dcat {CAT}
-- Part PRT named PRT_NME exists.
--
part {PRT, PRT_NME}
PK {PRT}
AK {PRT_NME}
-- It is possible for part PRT to have defect DEF.
--
part_defect {PRT, DEF}
PK {PRT, DEF}
FK1 {PRT} REFERENCES part {PRT}
FK2 {DEF} REFERENCES defect {DEF}
-- Equipment EQP named EQP_NME exists.
--
equipment {EQP, EQP_NME}
PK {EQP}
AK {EQP_NME}
-- Equipment EQP contains part PRT.
--
equipment_part {EQP, PRT}
PK {EQP, PRT}
FK1 {EQP} REFERENCES equipment {EQP}
FK2 {PRT} REFERENCES part {PRT}
-- Operator 0PR named OPR_NME exists.
--
operator {0PR, OPR_NME}
PK {0PR}
AK {OPR_NME}
-- Report type RTY named RTP_NME exists.
--
report_type {RTY, RTP_NME}
PK {RTY}
AK {RTP_NME}
-- Report category RCT named RCT_NME exists.
--
report_cat {RCT, RCT_NME}
PK {RCT}
AK {RCT_NME}
-- Report REP, of report-type RTY, named REP_NME,
-- categorized in report-category RCT,
-- was submitted by operator OPR on date-time DTE,
-- for equipment EQP with comments REP_CMT.
report{REP, RTY, REP_NME, RCT, OPR, DTE, EQP, REP_CMT}
PK {REP}
AK {REP_NME}
SK {REP, EQP}
FK1 {RTY} REFERENCES report_type {RTY}
FK2 {OPR} REFERENCES operator {0PR}
FK3 {EQP} REFERENCES equipment {EQP}
FK4 {RCT} REFERENCES report_cat {RCT}
-- Defect DEF for part PRT of equipment EQP is reported in
-- report-detail number DET_NO of report REP; with
-- additional comments DET_CMT.
--
report_detail {REP, DET_NO, EQP, PRT, DEF, DET_CMT}
PK {REP, DET_NO}
FK1 {REP, EQP} REFERENCES report {REP, EQP}
FK2 {EQP, PRT} REFERENCES equipment_part {EQP, PRT}
FK3 {PRT, DEF} REFERENCES part_defect {PRT, DEF}
Note:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key
Related
I am trying to design a relational database (postgres) which contains multiple tables under a single entity. In this example I have a store.
The store has many customers, staff, products. They are all related to the store through a "store_id"
I want to also link customers to a staff member. But I can't just add staff_id to the customers table, because this could allow a customer to be associated with a staff member from any store.
Is it possible to allow customers to be related only to staff which both the customer and staff are a member of?
Basically how do I prevent the below from happening?
Thanks for reading.
Solved this by applying a multi column foreign key constraint.
For customers, I keep the store_id foreign key, add a staff_id foreign key. Then also add a foreign key constraint against staff.store_id and staff.id
staff_id integer REFERENCES staff(id),
store_id integer REFERENCES stores(id),
CONSTRAINT customers_staff_id_store_id_fkey FOREIGN KEY (staff_id, store_id) REFERENCES staff(id, store_id)
This enforces a rule so customers can only be associated to staff of the same store
-- Person (user) USR exists.
--
user {USR}
PK {USR}
-- Store STO exists.
--
store {STO}
PK {STO}
-- Staff member (person) USR works at store STO.
--
staff {USR, STO}
PK {USR}
SK {USR, STO}
FK1 {USR} REFERENCES user {USR}
FK2 {STO} REFERENCES store {STO}
-- Customer (person) USR shops at store STO.
--
customer {USR, STO}
PK {USR}
SK {USR, STO}
FK1 {USR} REFERENCES user {USR}
FK2 {STO} REFERENCES store {STO}
-- Staff member STF manages account of customer CST
-- in store STO.
--
acc_mng {CST, STF, STO}
PK {CST}
FK1 {CST, STO} REFERENCES customer {USR, STO}
FK2 {STF, STO} REFERENCES staff {USR, STO}
Note:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key
I have a table called ProjectList. I have two other tables called Estimates and Orders.
The Primary keys for Estimates and Orders and are foreign keys in ProjectList. A ProjectList record is created first, then Estimate records are created and then and an Order record.
How would I create foreign key constraints in ProjectList for Estimates and Orders without violating the Order foreign key constraints?
The only thing I can think of is create an empty Orders record when an Estimate is created. Not sure if that is an elegant solution.
Well, the root problem here is a logical error: your DB model claims that it is possible to have a project estimate and an order before the project exists.
To illustrate the point, a logical model should look somehow like this:
-- Project PRO exists.
--
project {PRO}
PK {PRO}
-- Project estimate number EST_NO of project PRO exists.
--
estimate {PRO, EST_NO}
PK {PRO, EST_NO}
FK {PRO} REFERENCES project {PRO}
-- Project order number ORD_NO of project PRO exists.
--
order {PRO, ORD_NO}
PK {PRO, ORD_NO}
FK {PRO} REFERENCES project {PRO}
Note how you can not create an estimate or an order before the project. If for some reason you prefer single column IDs, then the example can be modified as:
-- Project PRO_ID exists.
--
project {PRO_ID}
PK {PRO_ID}
-- Project estimate identified by EST_ID
-- for project PRO_ID exists.
--
estimate {EST_ID, PRO_ID}
PK {EST_ID}
FK {PRO_ID} REFERENCES project {PRO_ID}
-- Project order identified by ORD_ID
-- for project PRO_ID exists.
--
order {ORD_ID, PRO_ID}
PK {ORD_ID
FK {PRO_ID} REFERENCES project {PRO_ID}
So, FKs in your example are reversed. Database design is all about logic, it stems from it. Although you may find a way to band-aid around the perceived technical problem using some SQL trickery, the underlying logical error (bug) will remain.
Note:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
FK = Foreign Key
I have the following db structure and am wanting to add in a new table called notepad:
ClinicTable (Id PK)
PatientTable (Id PK, ClinicId PK FK)
DoctorTable (Id PK, ClinicId PK FK)
ConsultationTable( Id PK, ClinicId PK FK, PatientId FK, DoctorId FK)
I'm waiting to hear back re: the business requirement, but the
notepad could either be tied to the consultation (1 to 1) or tied to
the patient (1 to M).
We are slowly restructuring and refactoring as
part of a new product build so I don't want to add the note to the
consultation table - I'd prefer to store it separately
A patient or consultation may or may not have a
notepad record, but a notepad record cannot exist without a patient
or a consultation.
A notepad record will always be entered by a single doctor and cannot be owned
by any other doctor
How do I determine whether to make the relationships identifying or non-identifying?
All of the other tables have the clinic Id in them, but I don't see that I need that?
I'm thinking it should look like the following...
If the note is tied to the patient then I have:
NotepadTable (Id PK, PatientId PK FK, DoctorId PK FK)
If the note is tied to the consultation then I have:
NotepadTable (Id PK, ConsultationId PK FK)
I am developing a system where there are doctor , patient and diagnosis.
I made diagnosis a weak entity because without a doctor or a patient there will not be a diagnosis.
now I want to make a relationship called treatment between doctor and patient and diagnosis where a specific doctor will treat a specific patient that has a specific diagnosis.
how to make the relationship given that diagnosis is a weak entity that will not have it's own primary key.
I think your fundamental understanding of weak entities and primary keys is flawed.
You seem to think that because the weak entity table "includes" the primary keys of two other tables, that means it can't have a primary key of its own.
This is not the case. A Primary Key can be the combination of multiple columns, as long as that combination is Unique for all rows.
Based on what you describe you should have something like this:
Table Doctor
Primary Key: DoctorID
Table Patient
Primary Key: PatientID
Table Diagnosis
Primary Key: DoctorID, PatientID (or an Identity column to form an artificial PK)
Foreign Key: DoctorID References Table Doctor
Foreign Key: PatientID References Table Patient
So finally,
Table Treatment
Primary Key: DoctorID, PatientID (, Identity column of Table Diagnosis if you created one)
Foreign Key: DoctorID References Table Doctor
Foreign Key: PatientID References Table Patient
This is sufficient if a doctor can only diagnose each patient once, and also can only suggest one treatment per patient. If either of these combinations can have more than one instance, then you should add some third "Line Number" type column to the PK of the Diagnosis and/or Treatment table to include in the PK for that table and make it unique.
20120304 - Streamlined question
Suppose we have entities R, D and E and this relational cardinalities
R < n:m > D
D < 1:n > E
The mapping of this specification is straight forward, but we have another requirement:
R < n:m > E
Side condition: E1 might only get 'assigned' to an R1, if E1 is related to some D1 and this D1 is related to the R1.
Unfortunately, even if E2 is related to a D2, which is related to an R2 - E2 might not be related to R2.
I'm in search of a relational DB model.
A model, which doesn't require multiple updates if a D gets detached from an Ra and reattached to another Rb. In this case, all Es of D need to get detached from Ra and attached to Rb too.
20120305 - Workaround?
A friend propose to create an entity DxR which links its D and its R by means of a tuple (D,R). Then create a relation
DxR < n:m > E
Hm...
20120302 - Original question
System is composed of top level zones (Z). A zone may have several regions (R).
So called departments (D) may be assigned to regions. One department may get assigned to more than one region, only if each region belongs to a different zone.
Finally, employees (E) belong to one and only one department.
Employees may get assigned to a region only if, employee's department belongs to the region.
Important: An employee need not belong to all regions its department belongs to.
Assume, that in the following graphics E1 belongs to D1. E1 should also belong to R1, but not belong to R2 - although D1 belongs to R1 and R2:
- Z Z
- __|___ ___|___
- R1 R R2 R
- \_________/
- D1
Q: Please propose the relations DB's table structure which models the above specification?
This question is very specific in one sense and some people might argue that it is too localized. There is, however, one more generally applicable idea that might be useful to other people in the future, so it isn't necessarily true that the question is too specific.
The really interesting part of these business rules is this one: (my emphasis added)
One department may get assigned to more than one region, only if each
region belongs to a different zone.
Here is a schema that captures almost all of the stated business rules declaratively without having to resort to any triggers.
create table ZONE
( ID int not null
, NAME varchar(50) not null
, constraint PK_ZONE primary key clustered (ID)
)
create table REGION
( ZONE_ID int not null
, REGION_ID int not null
, NAME varchar(50) not null
, constraint PK_REGION primary key clustered (ZONE_ID, REGION_ID)
, conttraint FK_REGION__ZONE foreign key (ZONE_ID)
references ZONE (ID)
)
create table DEPARTMENT
( ID int not null
, NAME varchar(50) not null
, constraint PK_DEPARTMENT primary key clustered (ID)
)
create table EMPLOYEE
( ID int not null
, NAME varchar(50) not null
, DEPT_ID int not null
, constraint PK_EMPLOYEE primary key clustered (ID)
, constraint FK_EMPLOYEE__DEPARTMENT foreign key (DEPT_ID)
references DEPARTMENT (ID)
)
The above tables are pretty obvious. However, there is one particular quirk: The REGION table has a compound primary key that includes the FK to ZONE. This is useful for propagating the constraint about departments having to be distinct within a zone.
Assigninging departments to regions requires an intersection table:
create table DEPT_ASGT -- Department Assignment
( REGION_ID int not null
, DEPT_ID int not null
, ZONE_ID int not null
, constraint PK_DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_DEPT_ASGT__REGION foreign key (ZONE_ID, REGION_ID)
references REGION (ZONE_ID, ID)
, constraint FK_DEPT_ASGT__DEPARTMENT foreign key (DEPT_ID)
references DEPARTMENT (ID)
, constraint UN_DEPT_ASGT__ZONES unique nonclustered (ZONE_ID, DEPT_ID)
)
This intersection table is pretty normal insofar as it has a foreign key to each of the tables that it links. What is special about this intersection table is the unique constraint. This is what enforces the rule that a department can't be in two different regions within the same zone.
Lastly, we need to map employees into departments and into regions. This requires another intersection table:
create table EMP_ASGT -- Employee Assignment
( REGION_ID int not null
, DEPT_ID int not null
, EMPLOYEE_ID int not null
, constraint PK_EMP_ASGT (REGION_ID, DEPT_ID, EMPLOYEE_ID)
, constraint FK_EMP_ASGT__DEPT_ASGT (REGION_ID, DEPT_ID)
references DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_EMP_ASGT__EMPLOYEE (EMPLOYEE_ID) refernces EMPLOYEE (ID)
)
You will note that the EMPLOYEE table has a foreign key to DEPARTMENT - That enforces the rule that each employee can belong to only one department. The EMP_ASGT table adds the details about which regions the employee participates in. Since an employee may not be involved in every region that his or her department is assigned to, the EMP_ASGT table connects employees to just those regions where they have some involvement.
Here is the one place where a trigger or some other procedural logic is needed. You need to make sure that EMPLOYEE.department_id stays consistent with the records in EMP_ASGT. You could try to push this into the declarative referential integrity by making the PK of EMPLOYEE a compound of ID and DEPT_ID, but that would force you to decide whether you want to violate 3NF or make your employee department changes a procedurally ugly mess. At the end of the day, a little trigger to make sure that EMP_ASGT doesn't disagree with EMPLOYEE.DEPT_ID would be much less trouble.