I have tables
Question (int id,string question, int questionNumber)
Option (int id, string option, int optionNumber)
How can I constrain pair (questionNumber, optionNumber) to be unique?
How can I apply this through Spring data JPA?
You have business keys; a question number and option numbers. A question number must uniquely identify a question. And an option number must uniquely identify an option within a question.
This would be something along the lines of:
CREATE TABLE question
(
question_number INT NOT NULL,
question VARCHAR(1000) NOT NULL,
PRIMARY KEY (question_number)
);
CREATE TABLE option
(
question_number INT NOT NULL,
option_number INT NOT NULL,
option VARCHAR(1000) NOT NULL,
PRIMARY KEY (question_number, option_number),
FOREIGN KEY (question_number) REFERENCES question(question_number)
);
You want to add technical IDs to your tables, though, and it seems you want to use them as primary keys. That makes this a little more complicated.
CREATE TABLE question
(
id INT NOT NULL,
question_number INT NOT NULL,
question VARCHAR(1000) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT uq_question UNIQUE (question_number)
);
CREATE TABLE option
(
id INT NOT NULL,
question_id INT NOT NULL,
option_number INT NOT NULL,
option VARCHAR(1000) NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (question_id) REFERENCES question(id),
CONSTRAINT uq_option UNIQUE (question_id, option_number)
);
With a database built on technical primary keys you want your IDs to be unique and your business keys, too. So you end up with more unique constraints in the database.
Related
I'm currently working on a database and I came across a new problem to me. The entities involved are Universe, Competition, Game, Pot. Here are the SQL files to create the tables:
CREATE TABLE Universe (
id int NOT NULL IDENTITY PRIMARY KEY,
history nvarchar (max),
creation_date date
);
CREATE TABLE Pot (
pot_name nvarchar(100),
universe_id int FOREIGN KEY REFERENCES Universe(id),
pot_description nvarchar(100),
media_description nvarchar(100),
is_official_pot bit
PRIMARY KEY (pot_name, universe_id)
);
CREATE TABLE Competition (
universe_id int NOT NULL FOREIGN KEY REFERENCES Universe(id),
compt_name nvarchar(100) NOT NULL,
alias nvarchar(100),
history nvarchar(max),
rules nvarchar (max),
winner_id nvarchar(100) FOREIGN KEY REFERENCES RaulUser(username),
edition int NOT NULL,
is_official_competition bit NOT NULL,
PRIMARY KEY (universe_id, compt_name, edition)
);
CREATE TABLE Game (
id int NOT NULL IDENTITY PRIMARY KEY,
pot_name nvarchar (100) NOT NULL,
universe_id int NOT NULL,
competition_name nvarchar(100) NOT NULL,
competition_edition int NOT NULL,
competition_round int NOT NULL,
home_raul_u_username nvarchar (100) FOREIGN KEY REFERENCES RaulUser(username) NOT NULL,
home_team nvarchar (100) NOT NULL FOREIGN KEY REFERENCES Team(team_name),
home_score int,
away_raul_u_username nvarchar (100) NOT NULL FOREIGN KEY REFERENCES RaulUser(username),
away_team nvarchar (100) NOT NULL FOREIGN KEY REFERENCES Team(team_name),
away_score int,
is_over bit NOT NULL,
played_date date,
FOREIGN KEY (universe_id, competition_name, competition_edition) REFERENCES Competition(universe_id, compt_name, edition),
FOREIGN KEY (universe_id, pot_name) REFERENCES Pot(universe_id, pot_name)
);
The problem starts with this last table (Game), as I can't use universe_id as a Foreign Key for different tables. What's the best approach to solving this? Creating an M:M table Game_Pot?
I only need to record the Pot of each Game because Pots change overtime and I don't want to lose that data.
Sorry for the long post and thank you all in advance :)
The only problem that I see is in the definition of table Game:
FOREIGN KEY (universe_id, pot_name) REFERENCES Pot(universe_id, pot_name)
Ordering of columns matters. The primary key of table Pot is (pot_name, universe_id), so you need to swap the columns in the foreign key, like so:
FOREIGN KEY (pot_name, universe_id) REFERENCES Pot(pot_name, universe_id)
Note that having identity (or the-like) primary key in every table might simplify your design: it would allow you to reduce the number of columns in the children tables, and to use single-column foreign keys. Meanwhile, you can still enforce uniqeness on columns tuples in the parent tables with unique constraints.
I want to create db for anime. This is my ER structure:
https://ibb.co/ctRk8f6
Any tips to improve this?
Every anime has blob for image and relations to brand and episode, each episode may have multiple links and relation to tag.
I wanted to know if this structure is good or should I make separate table for image or any other tip
CREATE TABLE Brand
(
id INT NOT NULL,
name INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE Tag
(
id INT NOT NULL,
name INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE Anime
(
id INT NOT NULL,
name INT NOT NULL,
img INT NOT NULL,
id INT,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Brand(id)
);
CREATE TABLE Episode
(
order INT NOT NULL,
rating INT NOT NULL,
date INT NOT NULL,
id INT NOT NULL,
PRIMARY KEY (order, id),
FOREIGN KEY (id) REFERENCES Anime(id)
);
CREATE TABLE Link
(
link INT NOT NULL,
host INT NOT NULL,
order INT NOT NULL,
id INT NOT NULL,
PRIMARY KEY (link, order, id),
FOREIGN KEY (order, id) REFERENCES Episode(order, id)
);
CREATE TABLE TagOfAnime
(
id INT NOT NULL,
id INT NOT NULL,
PRIMARY KEY (id, id),
FOREIGN KEY (id) REFERENCES Anime(id),
FOREIGN KEY (id) REFERENCES Tag(id)
);
A few issues here:
Why is everything of type INT? I would assume that name would be a nvarchar of some maximum length nvarchar(200) perhaps?
Your TagOfAnime table has two columns named id. That will not work. If they are references to the primary keys to the tag and Anime tables, then you should name them as such: Tag_id and Anime_id
I would not name a table Link. What is it "linking"? I would make it more descriptive.
In general, add a table if there can be multiple items associated with a single row in another table - as you are doing with the tags for Animes. Otherwise, if the data can appear in additional columns of a single row of the base table, then consolidate your tables to avoid complexity.
Other than that, ask specific questions where you are stuck and I'm sure someone will jump in to help.
I have two SQL tables: Job and Employee. I need to compare Job Languages Proficiencies and Employee Languages Proficiencies. A Language Proficiency is composed by a Language and a Language Level.
create table dbo.EmployeeLanguageProficiency (
EmployeeId int not null,
LanguageProficiencyId int not null,
constraint PK_ELP primary key clustered (EmployeeId, LanguageProficiencyId)
)
create table dbo.JobLanguageProficiency (
JobId int not null,
LanguageProficiencyId int not null,
constraint PK_JLP primary key clustered (JobId, LanguageProficiencyId)
)
create table dbo.LanguageProficiency (
Id int identity not null
constraint PK_LanguageProficiency_Id primary key clustered (Id),
LanguageCode nvarchar (4) not null,
LanguageLevelId int not null,
constraint UQ_LP unique (LanguageCode, LanguageLevelId)
)
create table dbo.LanguageLevel (
Id int identity not null
constraint PK_LanguageLevel_Id primary key clustered (Id),
Name nvarchar (80) not null
constraint UQ_LanguageLevel_Name unique (Name)
)
create table dbo.[Language]
(
Code nvarchar (4) not null
constraint PK_Language_Code primary key clustered (Code),
Name nvarchar (80) not null
)
My question is about LanguageProficiency table. I added an Id has PK but I am not sure this is the best option.
What do you think about this scheme?
Your constraint of EmployeeId, LanguageProficiencyId allows an employee to have more than one proficiency per language. This sounds counterintuitive.
This would be cleaner, as it allows only one entry per language:
create table dbo.EmployeeLanguageProficiency (
EmployeeId int not null,
LanguageId int not null,
LanguageLevelId int not null,
constraint PK_ELP primary key clustered (EmployeeId, LanguageId)
)
I don't see the point of table LanguageProficiency at the moment.
Same applies to the Job of course. Unless you would like to allow a "range" of proficiencies. But assuming that "too high proficiency" does not hurt, it can easilly be defined through a >= statement in our queries.
Rgds
Im wondering if on a relational table I set the two values below as a PRIMARY KEY if that automatically makes the table know that all entries should be unique....
CREATE TABLE UserHasSecurity
(
userID int REFERENCES Users(userID) NOT NULL,
securityID int REFERENCES Security(securityID) NOT NULL,
PRIMARY KEY(userID,securityID)
)
or do I need to be more explicit like this...
CREATE TABLE UserHasSecurity
(
userID int REFERENCES Users(userID) NOT NULL,
securityID int REFERENCES Security(securityID) NOT NULL,
PRIMARY KEY(userID,securityID),
UNIQUE(userID,securityID)
)
You don't need UNIQUE here. PRIMARY KEY will make sure there is no duplicate (userID,securityID) pairs.
No, you don't need to specify UNIQUE in addition to PRIMARY KEY. A primary key by definition must be unique.
A PRIMARY KEY has to be unique, so you only need to declare as a primary key. The underlying index is unique by definition.
Creating Unique Indexes
If I declare the table below does it implicitly imply that both the foreign keys make a unique primary key or do I need to do something more to make both attributes as a primary key?
CREATE TABLE Report_has_Items
(
ReportID int REFERENCES Report(ReportID) NOT NULL,
ItemID int REFERENCES Item(ItemID) NOT NULL
)
Essentially both attributes which are foreign keys from other tables, together would form a unique key.
No it doesn't. The above table has no primary key. If you want to use the fields as a primary key use:
CREATE TABLE Report_has_Items(
ReportID int REFERENCES Report(ReportID) NOT NULL,
ItemID int REFERENCES Item(ItemID) NOT NULL,
PRIMARY KEY (ReportID, ItemID)
)
or something similar depending on your sql dilect.
Let's name our constraints, eh?
CREATE TABLE dbo.Report_has_Items(
ReportID int NOT NULL,
CONSTRAINT [FK_RHI_Report] (ReportId) REFERENCES dbo.Report(ReportID),
ItemID int NOT NULL,
Constraint [FK_RHI_Item] (ItemId) REFERENCES dbo.Item(ItemID),
CONSTRAINT [PK_RHI] PRIMARY KEY (ReportID, ItemID)
)
I am not sure i understand your question completely but i assume you are trying to create a composite primary key (primary key with more than one attribute). You could do the following.
CREATE TABLE Report_has_Items(
ReportID int references Report(ReportID),
ItemID int references Item(ItemID),
PRIMARY KEY (ReportID , ItemID )
);
Note:The pair (ReportID , ItemID ) must then be unique for the table and neither value can be NULL.
Here is a very useful link for SQL Queries