Database normalization and duplication - database

I have a many to many relationship between bookmarks and tags:
Bookmarks
Id
UserId
Title
Url
Tags
Id
UserId
Title
Description
TagsBookmarks (junction table)
TagId
BookmarkId
As far as I know this is normalized and valid.
However it is possible that multiple users save the same bookmarks which means duplicate URLs in the bookmarks table. Does this kind of duplication belong to normalization and should it be avoided?
Update:
The system works like this:
User logs in and create bookmarks / tags.
A bookmark should have atleast one tag attached to it. For example: "http://google.com" may belong to tag "google" and "search-engine".
When a bookmark gets deleted the relation in TagsBookmarks also get deleted. The tags do not get deleted.
A user can delete a tag if it has no bookmarks.
A bookmark cannot exist without a tag.
A tag can exist without bookmarks.

Usually, table names and table columns are singular.
I would move UserID to TagBookmark.
Bookmark
--------
BookmarkID
BookmarkTitle
BookmarkURL
Tag
---
TagID
TagTitle
TagDescription
TagBookmark
-----------
UserID
TagID
BookMarkID
The primary (clustering) key of TagBookmark would be all 3 ID fields concatenated.
I'm not sure what the difference is between a TagTitle and a BookmarkTitle, so there may be some further normalization to be done.

You should exclude UserId from Bookmarks and Tags tables and add it to your junction table, because your system is user-centric as I understood from your explanation. Like this:
Users
Id
FirstName
...
Bookmarks
Id
Title
Url
Tags
Id
Title
Description
UsersTagsBookmarks (junction table)
UserId
TagId
BookmarkId
or even you need two junction tables, but it depends on your system logics:
TagsBookmarks (junction table 1, specifies all possible tags/bookmarks combinations)
Id
TagId
BookmarkId
UsersTagsBookmarks (junction table 2)
UserId
TagBookmarkId

Related

SQL Server : insert record when values or record do not exist

For the sake of simplicity, let's say I have two tables: one is called People and the other is called Contacting
People table:
ID primary key
NAME
WEBSITE
EMAIL
Contacting table:
ID (foreign key to People ID)
WAY_OF_CONTACTING
REFERENCE
The logic goes as follows: for every person there is in the People's table there could be several records on the Contacting's table. Obviously, the relationship between People and Contacting is one-to-many.
WAY_OF_CONTACTING could have only 2 values: "Email" and "Website", and the REFERENCE column contains the email or the website's name.
The primary key of the Contacting table is a composite primary key consisting of the ID and the Way_Of_Contacting (this means, for every ID, they can only have up to one email and one website)
The records on the people's table get deleted every night and get populated throughout the day.
4 things could happen in the People table:
Website and Email empty
Website empty but not Email
Email empty but not Website
Neither Website nor Email Empty
My problem is the following:
For every record in the People table
insert into Contacting a record when the ID exists in Contacting but doesn't have a record with Way_of_Contacting='Website' or when the ID doesn't exist in Contacting
insert into Contacting a record when the ID exists in Contacting but doesn't have a record with Way_of_Contacting='Website' or when the ID doesn't exist in Contacting
In other words:
If the People ID exists in the Contacting table, check if a record has the value "Email" on the field Way_of_Contacting.
If such record doesn't exist, and the Email field in the People table is not empty, insert a record.
If the ID doesn't exist and Email field in People is not empty, insert a record.
Same thing for Website
How could this be accomplished?
I've tried using merge and if not exists but I can't seem to find a correct answer
Can you try using a view instead of a table like below. The advantage being that the view is always updated based on the people table.
CREATE VIEW dbo.Contacting
AS
Select
ID
,'Website' as Way_of_Contacting
,WEBSITE as Reference
From People
Where WEBSITE is not null
Union all
Select
ID
,'Email' as Way_of_Contacting
,Email as Reference
From People
Where Email is not null

I want to create one common login table for different tables like Patient , Doctors, receptionist but not sure how to do it

I am using ASP.net MVC.
my question is that I have 2 tables patient and doctors and I want to create one common Userlogin table for both this table. So when I store username and password in UserLogin table it can determine whether it is Patient username or password or Doctor.
Can anyone please help me what should do? And give me some more idea about how and what I should change.
Doctors and patients are both subclasses of a more generic class, Users. You may want to research a topic called "Class Table Inheritance" There is a tag with that name here in Stackoverflow, and there are many articles on this topic on the web.
Class Table Inheritance is one way of making up for the fact that the relational model does not have a built in mechanism for inheritance.
Briefly, Your userlogin table needs a primary key, and username may not be suitable for this purpose. Call this key, UserId. Doctors and Patients do not need a unique id of their own. Instead, you can include UserId in both the doctor table and the patient table. This column should be the primary key of the doctor and patient table. In addition, this field should be named as a foreign key that references UserID in the UserLogin table.
The UserLogin table should probably include columns (fields) for all the features that are common to both doctors and patients, such as first name, last name, etc.
When you want to know if a user is a doctor or not, just join UserLogin and Doctor. Non doctors will drop out of the join.
Step-1. Create RoleMaster Table and add patient , doctors , receptionist as roleName in rolemaster table.
ColumnName Datatype
RoleId int
RoleName nvarchar(50)
Status bit
IsDeleted bit
CreatedDate datetime
step-2 Add RoleId As Reference in userLogin table and profileTable.

Handling multi-select list in database design

I'm creating a clinic management system where I need to store Medical History for a patient. The user can select multiple history conditions for a single patient, however, each clinic has its own fixed set of Medical History fields.
For example:
Clinic 1:
DiseaseOne
DiseaseTwo
DiseaseThree
Clinic 2:
DiseaseFour
DiseaseFive
DiseaseSize
For my Patient visit in a specific Clinic , the user should be able to check 1 or more Diseases for the patient's medical history based on the clinic type.
I thought of two ways of storing the Medical History data:
First Option:
Add the fields to the corresponding clinic Patient Visit Record:
PatientClinic1VisitRecord:
PatientClinic1VisitRecordId
VisitDate
MedHist_DiseaseOne
MedHist_DiseaseTwo
MedHist_DisearThree
And fill up each MedHist field with the value "True/False" based on the user input.
Second Option:
Have a single MedicalHistory Table that holds all Clinics Medical History detail as well as another table to hold the Patient's medical history in its corresponding visit.
MedicalHistory
ClinicId
MedicalHistoryFieldId
MedicalHistoryFieldName
MedicalHistoryPatientClinicVisit
VisitId
MedicalHistoryFieldId
MedicalHistoryFieldValue
I'm not sure if these approaches are good practices, is a third approach that could be better to use ?
If you only interested on the diseases the person had, then storing the false / non-existing diseases is quite pointless. Not really knowing all the details doesn't help getting the best solution, but I would probably create something like this:
Person:
PersonID
Name
Address
Clinic:
ClinicID
Name
Address
Disease:
DiseaseID
Name
MedicalHistory:
HistoryID (identity, primary key)
PersonID
ClinicID
VisitDate (either date or datetime2 field depending what you need)
DiseaseID
Details, Notes etc
I created this table because my assumption was that people have most likely only 1 disease on 1 visit, so in case there's sometimes several, more rows can be added, instead of creating separate table for the visit, which makes queries most complex.
If you need to track also situation where a disease was checked but result was negative, then new status field is needed for the history table.
If you need to limit which diseases can be entered by which clinic, you'll need separate table for that too.
Create a set of relational tables to get a robust and flexible system, enabling the clinics to add an arbitrary number of diseases, patients, and visits. Also, constructing queries for various group-by criteria will become easier for you.
Build a set of 4 tables plus a Many-to-Many (M2M) "linking" table as given below. The first 3 tables will be less-frequently updated tables. On each visit of a patient to a clinic, add 1 row to the [Visits] table, containing the full detail of the visit EXCEPT disease information. Add 1 row to the M2M [MedicalHistory] table for EACH disease for which the patient will be consulting on that visit.
On a side note - consider using Table-Valued Parameters for passing a number of rows (1 row per disease being consulted) from your front-end program to the SQL Server stored procedure.
Table [Clinics]
ClinicId Primary Key
ClinicName
-more columns -
Table [Diseases]
DiseaseId Primary Key
ClinicId Foreign Key into the [Clinics] table
DiseaseName
- more columns -
Table [Patients]
PatientId Primary Key
ClinicId Foreign Key into the [Clinics] table
PatientName
-more columns -
Table [Visits]
VisitId Primary Key
VisitDate
DoctorId Foreign Key into another table called [Doctor]
BillingAmount
- more columns -
And finally the M2M table: [MedicalHistory]. (Important - All the FK fields should be combined together to form the PK of this table.)
ClinicId Foreign Key into the [Clinics] table
DiseaseId Foreign Key into the [Diseases] table
PatientId Foreign Key into the [Patients] table
VisitId Foreign Key into the [Visits] table

Microsoft Access 2013 - Multiple Foreign Keys in the same Record

I’ve encountered a problem with pulling multiple foreign keys into one record in a Microsoft Access table.
I’ve got two tables with these fields:
Table 1:
Owners
Fields:
Owner ID (Primary Key)
First Name
Last Name
Table 2:
Ships
Fields:
Ship ID (Primary Key)
Ship Name
I need to create a relationship between Table 1 and Table 2 which shows who owns the ship. I’ve tried adding a number field to Table 2 called Owner ID (Foreign Key) and this works absolutely fine.
Working Example:
Table 1 – Owners Table 2 – Ships
Owner ID (Primary Key)__ Ship ID (Primary Key)
First Name \ Ship Name
Last Name \________Owner ID (Foreign Key)
Unfortunately my ships in Table 2 can have multiple owners (up to 5) at the same time. My problem arises when I try to create a series of linking fields in Table 2.
Not Working:
Table 1 – Owners Table 2 – Ships
Owner ID (Primary Key)__ Ship ID (Primary Key)
First Name \ Ship Name
Last Name \ Owner1 ID (Foreign Key)
\______/ Owner2 ID (Foreign Key)
\ Owner3 ID (Foreign Key)
Can anyone recommend any workarounds so I can show multiple owners taken from the Owners table in the Ships table?
Thanks for your help!
Your database design is definitely incorrect.
In the case you explain, you have a many-to-many relationship between Ships and Owners, which MUST translate into a "relationship table" in the relational model.
In this case: a [Ownership] table, with 2 fields, being the 2 Primary Keys (PK) of the related tables.
In other words, you need 3 tables:
Ships(ShipId, ShipName, Whatever) PK is ShipId
Owner(OwnerId, FirstName, LastName) PK is OwnerId
OwnerShip(ShipId, OwnerId) PK is made of the 2 FKs
The problem is that it looks like Access doesn't allow Nullable FK's and so all Owner fields would have to be filled in, no matter how many owners there are.
The only solution to this I can think of is to introduce a ShipOwner table, which has ShipID and OwnerID columns (as FK's to the Ship and Owner tables). You can then have as many Owners as you like.
Pros: You can add things like %Owned if that matters
Cons: The software has to enforce the limit of 5 owners
Biggest Pro: it will work!
Cheers -
EDIT: The first para is wrong: Access does let you add nullable FK's. However I still thing the suggestion here is a good one. Repeating Groups (Owner 1 to 5) is against Normalisation rules, and this suggestion is normalised.

Movie database relationship

I'm designing a database that stores movie related information. I'm stuck on a problem and can't seem to know how to solve it.
So I'm creating a database that store movies, and for my movie table these are its attributes
-movieID NUMBER PRIMARY KEY,
-title VARCHAR(10),
-genres genre_varray,
-producers
-director
-cast
I'm going to create another tables for producers, cast and director. My problem is for the fields producers and cast I have to insert a list of people and the cast I have to add a role to each actor, I'm not sure how I would do that, I was thinking of using nested table? Another problem is that a person can be either actor, director, producer or all.
What I have so far is
supertype person_type - personID, name, sex
subtype actor_type - country
subtype director_type - country
subtype producer_type - company
table of people of type person_type
table of movie_people - profession
Thanks for any help.
Any person can perform one or more roles on a movie, and the roles they perform will be different for different movies.
I would have a table of people, a table of movies, a table of role types (eg:Actor, Director, Producer,etc) , and a table linking all three with fields of (PersonID, MovieID, RoleID)
I would also have a separate table for MovieGenres rather than the array you have detailed.
In total, you need six tables:
GENRES
GenreID
GenreName
ROLES
RoleID
RoleName
PEOPLE
PersonID
PersonName
MOVIES
MovieID
MovieName
MovieYear
CASTLIST
CastID
MovieID
PersonID
RoleID
MOVIEGENRE
MovieID
GenreID
A person can appear in the castlist of a movie in several roles, which is why I have given the table a surrogate id. Otherwise you will need a primary key composed of all three foreign keys (and that assumes that you want to list a person playing three different characters only once - check out Dr Strangelove).
Edited to include the MovieGenre table.

Resources