MS SQL Server 2012 Auto-Increment & Primary/Foreign Keys - sql

I'm trying to see if the Primary/Foreign keys can be used in the following way in MS SQL server 2012.
If I have two tables one with employer information and one with recruiter information.
If any given employer can have up to 5 recruiter accounts, then in my table each time a new recruiter account is created with the employer's PK ID in a matching column on the Recruiters table and have a matching field on the recruiters table that has a count of the # of recruiter accounts that exist in the recruiters table.
So
Employers Table = A
EmployerID int Unchecked
UserID int Checked
AccountStatus varchar(50) Checked
CompanyName varchar(150) Checked
JobsPosted int Checked
ResumeViews int Checked
ResumeFavorites int Checked
Recruiters int Checked
Recruiters Table = B
RecruiterID int Unchecked
EmployerID int Checked
UserID int Checked
AccountStatus varchar(50) Checked
JobsPosted int Checked
ResumeViews int Checked
ResumeFavorites int Checked
For each Recruiter that exists in table B auto-increment the value in Table A's Recruiters field.
Is that proper use of primary/foreign keys? Or should I be using TSQL to accomplish this?

I think you are missing the point of normalizing your database.
Let your employer data in the Employee and Recruiter data in the Recruiter and a EmployerRecruiterAccount table where 1 employer can have 5 recruiters.
So your EmployerRecruiterAccount will have EmployeeID and RecruiterID as foreign keys.

Related

Normalizing a table with duplicate rows and many-to-many relationships

I am designing the database for an accounting system, currently working on the Expenses table.
According to IRS rules, whenever you update a row in any accounting table, you need to cancel out the existing row by negating its values, and create a new row with the modified information, like so:
Set the row's Status flag to "Modified"
Create an identical copy of this row, with all Money fields negated, so that the sum of the two rows is 0
Create a 3rd row, identical to the first one, with the modified data
Each expense has an identity field called ID for internal identification purposes, and an ExpenseID field, which identifies the transaction to the users. The two cannot be the same, because
ExpenseID can be repeated twice if the transaction was modified and its row was duplicated.
ExpenseIDs MUST be consecutive and NEVER have gaps, while identity fields can skip numbers if a transaction is rolled back and the identity is not reseeded.
In general, I believe the primary key should have no business meaning whatsoever.
My problem is that there are other tables used to link these expenses Many-To-Many to other objects in our system. E.g.: each expense can be linked to documents, folders, users, etc.
So it looks something like this:
create table Expenses (
ID int not null identity(1,1),
ExpenseID int not null,
Amount Money not null,
Status tinyint not null,
[...]
)
create table Expenses_Users (
ExpenseID int not null,
UserID int not null
)
alter table Expenses_Users add constraint FK_Expenses_Users_Expenses
foreign key (ExpenseID) references Expenses (ID)
alter table Expenses_Users add constraint FK_Expenses_Users_Users
foreign key (UserID) references Users (ID)
Now, because of the IRS guidelines, I have to duplicate not only rows in the Expenses table, but also in Expenses_Users, and any other table that links Expenses to other tables.
I have two ideas on how to solve this:
Option One: Normalize Expenses like this:
create table Expenses (
ID int not null identity(1,1),
ExpenseID int not null,
Status tinyint not null,
[...]
)
create table ExpensesNormalized (
ExpenseID int not null,
Amount Money not null
)
alter table ExpensesNormalized add constraint FK_ExpensesNormalized_Expenses
foreign key (ExpenseID) references Expenses(ExpenseID)
This means I'll only have to link external tables to Expenses, not ExpensesNormalized. Also, when updating an expense, I'll only duplicate and negate the data in ExpensesNormalized, which means I'll have far less redundant data in the Expenses table.
However, I'll have to use a JOIN clause every single time I SELECT from Expenses. I fear a performance hit because of this.
Option Two: Use the same tables I use now, but have the field Expenses_Users.ExpenseID point to the field Expenses.ExpenseID. This means that I won't have to duplicate any external objects because they'll point to ExpenseID, which may occur several times.
However, this will not be a real foreign key because SQL Server does not allow foreign keys to non-unique fields, so I'll have to implement foreign key logic in a trigger.
I'm having a hard time deciding between these two options. Any feedback would be appreciated.

Accounts database design

Hello everyone i am developing an accounts package for my company using Sql Server 2008 and VB.Net.
I need some help regarding the database design.
I have the following tables
AccountsGroupMaster
GroupId int
GroupName nvarchar(50)
ParentGroupId int
CatId int
PrimaryGroup bit
CreatedByUser nvarchar(50)
CreatedOn datetime
The above table will store the Groups for the accounts eg: Current Assets etc.
Accounts Table
AccCode nvarchar(6)
AccountName nvarchar(30)
ParentAcc nvarchar(6)
GroupId int
The above table stores the Accounts/Ledgers .
VoucherMain
VoucherNo bigint
VoucherDate datetime
DebitCredit int (0 for Credit 1 for Debit)
AccCode nvarchar(6) (Account Code to be debited/Credited)
UserID nvarchar(30)
VoucherDetails
VoucherNo bigint
SlNo int
AccCode nvarchar(6) (Debit this account if account in VoucherMain credited/ Credit this account if account in VoucherMain Debited)
Amount decimal(18, 2)
Narration nvarchar(MAX)
The above two tables store the transactions.The above two tables linked by the VoucherNo columns
Now my question is whether i should maintain all the bank accounts in the accounts table or should i have a separate table for the bank accounts.
As each bank account should have its respective ledgers.
Please help me in the design of this database.
thanks
Is a BankAccount different than an Account? If it's a different entity entirely then it would probably call for its own table. If it's just a certain kind of Account then it might not. In that case, there could be other options:
For example, you could add an AccountType to the Account table to determine which ones are BankAccount types and which ones are not.
Or, if the difference is more than just a type flag and includes additional Account-level columns of data which are applicable only to that specific type of Account instances, then you might make a sub-table. It would be a BankAccounts table, but its primary key would also be a foreign key to the Accounts table, creating an enforced 0-1 relationship between the two.
Then, whenever creating a BankAccount record you'd first add a record to the Accounts table, get the generated key, and use that key to add a record to the BankAccounts table.

cross-referencing tables

I have 3 tables, Chapters, SubChapters, and Divisions . Each of these tables have additional records that I would like to store in a table called 'Sections'. They are all 1:many relationships.
My question is what would be the best way to establish the cross reference here? This is what I currently have:
Chapter table:
chapterID int
partID int
chapterNumber varchar
chapterName varchar
SubChapter table:
subChapterID int
chapterID int
subChapterNumber varchar
subChapterName varchar
Division Table:
divisionID int
subChapterID int
divisionNumber varchar
divisionName varchar
Section Table:
sectionID int
parentID int
parentType int (1 = chapter; 2 = subchapter; 3 = division)
sectionNumber varchar
sectionName varchar
The issue I'm running into here are FK restraints. Should I just do away with the foreign keys? What could I do to improve efficiency if I did or would that even be a concern?
For those wondering, my requirements are to have certain aspects of State and Federal administrative code accessible in a database to populate drop-down menus on the intranet webpages.
Personally, I would create a section table for each parent type and then your foreign keys would work properly. I would then create a view to join up all the joins to alleviate the repetitive nature of joining those six tables.
I can certainly appreciate the design you have now, but having the FKs make it nice in preventing orphaned data. Another alternative is to add delete triggers to Chapters, SubChapters, and Divisions to escape the deletion if there is a corresponding Sections record.

Database design for flagging system

I have a database which captures information relating to a patient for a medical practice. This information is spread across several tables:
Patient - For contact information
PatientMedicalHistory - For medical conditions unrelated to the current problem
PatientEpisode - Financial information for the current visit
PatientEpisodeReason - Stuff relating to why the patient is here today
I want to introduce a flag system, so that any messages will appear when bringing up the patient details. So for example, if the patient has had a heart attack previously this would need to be flagged (that info would be in PatientMedicalHistory).
My current approach is to set up a flag lookup table which defines the flag type, and the table/column that the flag is referring to and what the value would be in order to raise that flag:
CREATE TABLE FlagType
(
ID INT PRIMARY KEY IDENTITY,
TypeName NVARCHAR(300) NOT NULL,
Colour NVARCHAR(100) NOT NULL,
Urgency INT NOT NULL
)
CREATE TABLE Flag
(
ID INT PRIMARY KEY IDENTITY,
FlagTypeID INT NOT NULL REFERENCES FlagType(ID),
TableName NVARCHAR(300) NOT NULL,
FieldName NVARCHAR(300) NOT NULL,
FlagValue NVARCHAR(300) NOT NULL
)
This seemed all very well, but then trying to write either a) a stored procedure that doesn't resemble a mess or b) a LINQ query that doesn't kill performance seems difficult.
Is there any alternatives to this? The issue is that the flag could be defined on any column in any of the tables above. This totals about 80 columns in total.
You can add three fields to PatientMedicalHistory table: organ, disease, criticality.
When a patient comes in with a problem, you can pull patient history based on the same organ or disease presented in the current episode where the criticality meets a certain threshold. What you are doing here is classifying your patient history data so it relates to the current episode data.

Creating foreign key in Visual Studio 2010

I'm trying to create 2 tables in Visual Studio server pane and I have a problem creating the foreign keys.
When I'm trying to create them in the relationship page it won't let me create foreign keys until I make them primary keys.
I don't understand why I can't have a different member in my table that it is primary key and a different one a foreign key.
My tables are like this:
Table People:
Primary key: ID int
Name nvarchar
Age int
City nvarchar
Foreign key: AccountNumber int --> when I make him primary key everything works.
Table BankAccount:
Primary key and Foreign Key: AccountNumber int
Money float
ps.
I used some mysql with CMD and I remember that I could do this, but because I don't have this control in visual studio I'm lost.
UPDATE:
Rup made a good point that i only relize afther answering the qustion he ask me
i just did the realtionship (Foreign Key) for the bank account table and now i got
what i wanted thank you!
Why is BankAccount.AccountNumber a Foreign Key? Are you trying to reference back to the the person who owns it?
If that is the case, BankAccount should be:
CREATE TABLE BankAccount
(
AccountNumber int PK,
Money float, // bad idea. Use currency or int (i.e. store balance as pennies)
Owner int FK REFERENCES People.ID
)
And drop the account ID from the people table.
This models the relationship "an Account has 1 and only one owner" and allows the relationship "A person can have many accounts."
It looks like what you're trying to do is create a back reference. If you were to choose to do this, then the back reference to the owner should be on People.ID, not on account. -- Although this is unnecessary because you can simply query
SELECT * FROM
BankAccount INNER JOIN People ON BankAccount.Owner = People.ID
to get all accounts and their owners.
If you want to establish multiple owners for an account, AND many accounts per user, then you need to establish a third table to implement the many-to-many relationship.
CREATE TABLE AccountOwners
(
AccOwnID int PK,
AccountID int FK REFERENCES BankAccount.AccountNumber,
PeopleID int FK REFERENCES People.ID
)
And drop the People.AccountNumber and BankAccount.Owner. This technique is akin to maintaining a list of all accounts and owners which you can query.