I'm making a C#/SQL/LINQ web form site to handle a single season in Formula 1. The tricky part appears to be designing tables for single races, each describing around 20 drivers, teams they drive with (2 drivers per team, not necessarily the same drivers all season) and position in the race.
So far I have the tables
Driver (driverid(PK), firstname, lastname, teamid(FK)
Team (teamid(PK), teamname, engine)
Circuit (circuitid, circuitname, country)
For storing race results I have a Race table
dbo.Race
raceId(PK)
date
circuitId(FK)
and a table for each race with 20 records which will be linked to corresponding entry in Race (analogous to an List as a class field in object-oriented design) eg.
dbo.Australia2018
driverid(FK)
teamid(FK)
finalposition
finaltime
The alternative to having a new table for each race was to have 20 other fields in the Race table but either way there is a lot of data to be stored. Obviously I need to search through each race to total points for Drivers and Constructors (Team) results.
For this amount of data there will be no 'correct' way of designing, but is there a neater way I'm missing here?
Something like this should do what you wanted.
You could create a table for each driver, this would hold all of the information about that driver, it would also have a foreign key for the team they belong to. This would allow you to query all drivers & teams seperately to races.
CREATE TABLE Driver
(
Driver_ID INT IDENTITY(1,1) PRIMARY KEY,
Forename varchar(100),
Surname varchar(100),
Team_ID INT
)
You could use a linking table to link the driver to the team and when their realationship started and ended
CREATE TABLE Driver_Team
(
Driver_Team_ID INT IDENEITY(1,1) PRIMARY KEY,
Team_ID INT,
Driver_ID INT,
Start_date datetime,
End_date datetime
)
There would be another table for the teams, all team information could live here.
CREATE TABLE Teams
(
Team_ID INT IDENTITY(1,1) PRIMARY KEY,
Team_Name varchar(100)
)
ALTER TABLE Driver ADD CONSTRAINT FK_TeamID FOREIGN KEY (Team_ID) REFERENCES Teams (Team_ID)
A table for the circuits or tracks, here you could put all information about the track
CREATE TABLE Circuit
(
Circuit_ID INT IDENTITY(1,1) PRIMARY KEY,
CircuitName varchar(200)
)
Now the race table you would have the driver id, team id and circuit id these are foreign keys from other tables, then you could have all the other race information such as the race date, final position and final time
CREATE TABLE Race
(
Race_ID INT IDENTITY(1,1) PRIMARY KEY,
Race_Date DATETIME,
Driver_ID INT,
Team_ID INT,
Circuit_ID INT,
FinalPosition TINYINT,
Final_Time DATETIME
)
ALTER TABLE Race ADD CONSTRAINT FK_Race_DriveID FOREIGN KEY (Race_ID) REFERENCES Driver(Race_ID);
ALTER TABLE Race ADD CONSTRAINT FK_Race_Team FOREIGN KEY (Team_ID) REFERENCES Teams(Team_ID);
ALTER TABLE Race ADD CONSTRAINT FK_Race_CircuitID FOREIGN KEY (Circuit_ID) REFERENCES Circuit(Circuit_ID);
Once you have all of your data in the tables you could select the data from the database using something like this.
SELECT
D.Forename,
D.Surname,
T.TeamName,
C.CircuitName,
R.FinalPosition,
R.Final_Time
FROM Race R
INNER JOIN Driver D ON
D.Driver_ID = R.Driver_ID
INNER JOIN Teams T ON
T.Team_ID = R.Team_ID
INNER JOIN Circuits C ON
C.Circuit_ID = R.Circuit_ID
WHERE C.CircuitName = 'Silverstone' AND D.Forename = 'Lewis'
Related
I'm building a rental application for school. There will be three groups will have access to this application. Managers, Associates and Owner. Each group may have restrictions on the functionality. My issue is that I created a login form and I need to redirect the user(according to their group) to another form. I need to create a table with users and groups to be able to cal a certain group when the user enters their Username and Password.
I've tried to create a table, but then I got stuck on which data should I put as a foreign key.
CREATE TABLE Users (
UserID INT NOT NULL,
PASSWORD VARCHAR(50),
PRIMARY KEY(UserID)
);
CREATE TABLE Groups (
GroupID INT,
GroupName VARCHAR,
PRIMARY KEY(GroupID)
);
CREATE TABLE User_Groups (
UserID INT,
GroupID INT,
);
If a user belongs exactly to one group, and it looks like this is the case here, you better put the group ID in the user table. Constraint it as a foreign key to the ID in the groups table, to be sure only valid group IDs can be inserted, and as not null, to enforce that it has to be set.
CREATE TABLE groups
(grouid integer,
groupname varchar(50),
PRIMARY KEY (groupid));
CREATE TABLE users
(userid integer,
username varchar(50),
password varchar(50),
grouid integer NOT NULL,
PRIMARY KEY (userid),
FOREIGN KEY (groupid)
REFERENCES groups
(groupid));
I have created the audit table similar to the below code which logs the changes made on the source table. My question is can a audit table contain newly inserted record or it should contain only the updated records/history since the new record is there in source table ?
I am Looking for pros/cons on each approach and best practice.
create table tblOrders
(
OrderID integer Identity(1,1) primary key,
OrderApprovalDateTime datetime,
OrderStatus varchar(20)
)
create table tblOrdersAudit
(
OrderAuditID integer Identity(1,1) primary key,
OrderID integer,
OrderApprovalDateTime datetime,
OrderStatus varchar(20),
UpdatedBy nvarchar(128),
UpdatedOn datetime
)
go
create trigger tblTriggerAuditRecord on tblOrders
after update, insert
as
begin
insert into tblOrdersAudit
(OrderID, OrderApprovalDateTime, OrderStatus, UpdatedBy, UpdatedOn )
select i.OrderID, i.OrderApprovalDateTime, i.OrderStatus, SUSER_SNAME(), getdate()
from tblOrders t
inner join inserted i on t.OrderID=i.OrderID
end
go
It is totally based on your case,
But I would like to have the Audit table to have all records, the new inserted and the updated, so that I can view, check history, do time line calculations,... using just the Audit table as a separate entity without going back to the original table.
Also It might be helpful if I want to roll back to a certain record (it could be the first inserted one)
I am having problems with my MSSQL database design.
I had 2 tables that looked like this:
CREATE TABLE tenants
(
tenantId INT PRIMARY KEY,
tenantName VARCHAR
)
CREATE TABLE users
(
userId INT PRIMARY KEY,
userName VARCHAR,
tenantId INT,
FOREIGN KEY (tenantId) REFERENCES tentants(tenantId)
)
I wanted to switch from only IDs to GUIDs for uniqueness and changed the tables.
I have read that GUIDs as primary keys are not recommended for performance reasons. So I kept the IDs:
CREATE TABLE tenants
(
tenantId INT PRIMARY KEY,
tenantGuid UNIQUEIDENTIFIER,
tenantName VARCHAR
)
CREATE TABLE users
(
userId INT PRIMARY KEY,
userGuid UNIQUEIDENTIFIER,
userName VARCHAR,
tenantGuid UNIQUEIDENTIFIER,
FOREIGN KEY (tenantGuid) REFERENCES tentants(tenantGuid)
)
Now Entity Framework is going wild just dismissing all relationships because the guids are not part of the primary key.
On old posts I have read that this would be not supported. Is it still not supported?
How am I support to solve this?
Thanks a lot!
Also sorry for the bad formatting, the editor doesn't respect my line breaks :/
soomon
I wanted to switch from only IDs to GUIDs for uniqueness and changed the tables.
You don't really need to switch to GUIDs to ensure uniqueness.Your IDs will be guaranteed to be unique (whichever type they are, say integer) as long as they are set as your primary keys.
I have read that GUIDs as primary keys are not recommended for performance reasons. So I kept the IDs
tenantGuid uniqueidentifier foreign key to tenants.tenantGuid
Assuming you're talking about performance of 'joins' when using GUID as the key then keeping ID's as primary key will not make a difference since queries will be made on the GUID anyway.
Now entity framework is going wild just dismissing all relationships because the guids are not part of the primary key.
How am I support to solve this?
I believe you're better off not solving this and rather choosing either to go back to your previous database design which uses the integer ID. Or ultimately use GUID as your primary key (removing integer ID in the process).
If you still want to us the unique identifier, you need to take note on the below two things
Set the tenants.tenantGuid to UNIQUE KEY and also set the users.tenantGuid as the same data type
Modify the tables as below
CREATE TABLE tenants (
tenantId INT PRIMARY KEY,
tenantGuid UNIQUEIDENTIFIER UNIQUE,
tenantName VARCHAR
)
CREATE TABLE users (
userId INT PRIMARY KEY,
userGuid UNIQUEIDENTIFIER,
userName VARCHAR,
tenantGuid UNIQUEIDENTIFIER,
FOREIGN KEY (tenantGuid) REFERENCES tenants(tenantGuid)
)
Hope this works for you
In Library Management System, how to keep transaction done by student in taking book....I have got two table Student and Book which have one to many relationship...Now if any student is issuing 5 different book then how this information is stored in Database?? please help
A Student can borrow zero or more Books, a Book is borrowed by zero or more Students. This is a textbook many to many relationship and it requires a third table
So you need a Borrows table with a structure like this
Create Table Borrows
(
IDBook int not null,
IDStudent int not null,
BorrowDate smalldatetime not null,
ReturnDate smalldatetime null,
BookStatusBefore nvarchar(32) not null,
BookStatusAfter nvarchar(32) not null
)
-- Primary key on IDBook+IDStudent....
ALTER TABLE Borrows ADD CONSTRAINT PK_Borrows PRIMARY KEY CLUSTERED
(
IDBook,
IDStudent
)
Now you can register a Borrow event and keep track of the whereabout of a book and other historical information about the event itself.
Designing a database with many tables and want to add a general Note table. I want a Note object to be able to attach to several other tables. So one Note can be associated with a particular Contact, maybe a Job, and also a few different Equipment objects. I'd like to be able to filter Note objects by the particular objects they are associated with.
Well, here's one way:
CREATE TABLE NoteTables
(
TableID INT NOT NULL Identity(1,1),
TableName SysName NOT NULL,
CONSTRAINT PK_NoteTables PRIMARY KEY CLUSTERED(TableID)
)
GO
CREATE TABLE TableNotes
(
TableID INT NOT NULL,
RowID INT NOT NULL,
NoteID INT NOT NULL,
CONSTRAINT PK_NoteAttachments PRIMARY KEY CLUSTERED(TableID, RowID, NoteID)
)
GO
CREATE TABLE Notes
(
NoteID INT NOT NULL Identity(1,1),
Note NVARCHAR(MAX),
CONSTRAINT PK_Notes PRIMARY KEY CLUSTERED(NoteID)
)
Note that I am assuming SQL Server and the use of IDENTITY columns here (if Oracle, you can use Sequences instead).
The Notes table contains all of the notes and gives them an ID to use as both a referemce and a primary key.
The NoteTables just list all of the tables that can have note attached to their rows.
TableNotes links the notes to the tables and rows that they are attached to. Note that this design assumes that all of these tables have INT ID columns that can be used for unique referencing.
It would take you two tables. Structure is as easy as the following.
Note table:
NotePK | tableFK | note
And a table that lists all your tables.
Either you create one (then you have full control but need to maintain it) or you take the
sys.tables t
You read it out by SELECT * FROM sys.tables t
the column object_id would be your tableFK in the first table
You can store as many comments as you like. If you want to get the note simply query the note table and filter for your tableFK.