I have a partially translate SQL script and several like it that look something like this:
CREATE TABLE STATUSES
( STATUS_ID CHAR(1) NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL,
EVENT NUMBER(3) NOT NULL,
RESOLUTION NUMBER(3) NOT NULL,
CONSTRAINT PK_STATUSES PRIMARY KEY CLUSTERED (STATUS_ID ASC));
They were tables defined in SQL Server and I am looking to translate them for use in Oracle, however I am unsure how to handle the CLUSTERED part of the constraint and the ASC attribute of the Primary Key, I have seen some articles out there but they have served to be unhelpful. Can anyone help me complete this, or point me to an article that can help?
Just ignore them. You can remove both the clustered and the asc and the table should be fine in both databases.
I would be inclined to just use the primary key keyword, instead of an explicit constraint:
CREATE TABLE STATUSES (
STATUS_ID CHAR(1) NOT NULL PRIMARY KEY,
DESCRIPTION VARCHAR2(50) NOT NULL,
EVENT NUMBER(3) NOT NULL,
RESOLUTION NUMBER(3) NOT NULL
);
Your table is too small to worry about clustered indexes. It is questionable whether any index at all is useful on such a small table.
Related
I'm having some difficulties with a database I'm creating for a summer camp, specifically with the PK and FK constraints. When I declare the FK constraint (e.g. FOREIGN KEY(PID) references Campers(CamperID)) I get an error running my code through pgAdmin (I'm using PostgreSQL). I understand that, for example, the Campers table is not yet created, and this is most likely part/all of the roadblock, however I feel like my FKs are still wrong somehow. To my understanding, a FK is a PK in another table -- but I feel like there is some redundancy or disconnect between my tables.
I've put the syntax for some of my CREATE statements below. I'm not sure if I'll get reprimanded for the quality of my (somewhat vague) question, but I feel a bit lost and would appreciate any help or advice. Thank you in advance!
DROP TABLE IF EXISTS People;
CREATE TABLE People (
PID VARCHAR(10) NOT NULL UNIQUE,
FName TEXT NOT NULL,
LName TEXT NOT NULL,
DOB DATE NOT NULL,
ArrivalDate DATE NOT NULL DEFAULT CURRENT_DATE,
DepartureDate DATE,
US_PhoneNum VARCHAR(11) NOT NULL,
StreetAddress VARCHAR(200) NOT NULL,
Sex GENDER NOT NULL,
ZIP VARCHAR(10) NOT NULL,
PRIMARY KEY(PID),
FOREIGN KEY(PID) REFERENCES Campers(CamperID),
FOREIGN KEY(PID) REFERENCES Counselors(CounselorID),
FOREIGN KEY(ZIP) REFERENCES Zip(ZIP)
);
DROP TABLE IF EXISTS Zip;
CREATE TABLE Zip (
ZIP VARCHAR(10) NOT NULL,
City TEXT NOT NULL,
State VARCHAR(2) NOT NULL,
PRIMARY KEY(ZIP)
);
DROP TABLE IF EXISTS Campers;
CREATE TABLE Campers (
CamperID VARCHAR(10) NOT NULL REFERENCES People(PID),
AgeGroup AGES NOT NULL,
CabinID VARCHAR(2) NOT NULL,
Bed BEDTYPES NOT NULL,
GroupID VARCHAR(3) NOT NULL,
PRIMARY KEY(CamperID),
FOREIGN KEY(CamperID) REFERENCES People(PID),
FOREIGN KEY(CabinID) REFERENCES Cabins(CabinID),
FOREIGN KEY(Bed) REFERENCES Beds(Bed),
FOREIGN KEY(GroupID) REFERENCES Groups(GroupID)
);
DROP TABLE IF EXISTS Counselors;
CREATE TABLE Counselors (
CounselorID VARCHAR(10) NOT NULL REFERENCES People(PID),
GroupID VARCHAR(3) NOT NULL,
CabinID VARCHAR(2) NOT NULL,
PRIMARY KEY(CounselorID),
FOREIGN KEY(GroupID) REFERENCES Groups(GroupID),
FOREIGN KEY(CabinID) REFERENCES Cabins(CabinID)
);
ERROR message for further clarification:
ERROR: relation "campers" does not exist
********** Error **********
ERROR: relation "campers" does not exist
SQL state: 42P01
There are more tables (obviously) which I can provide the create statements for, if needed.
You should really start here: Foreign key.
In the context of relational databases, a foreign key is a field (or
collection of fields) in one table that uniquely identifies a row of
another table.
What you are trying to do in your script is to create a circular link between People, Campers and Counselors. Having a Primary Key field also a Foreign Key mandates that IDs across all referenced tables are identical.
... and to create a Foreign Key the referenced table must already exist in the database. So you should start with the table that does not have any Foreign Keys and create tables that reference only those tables created previously. Alternatively you can create all tables without Foreign Keys and add them later, when all the tables are present.
... and to answer the question, Foreign Keys are never necessary, but they might 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
Are these T-SQL declarations equals?
CREATE TABLE Person
(
ID INT PRIMARY KEY,
NAME VARCHAR(60)
)
CREATE TABLE Dog
(
CHIP_ID INT PRIMARY KEY,
OWNER_ID INT REFERENCES Person(ID)
)
and
CREATE TABLE Person
(
ID INT PRIMARY KEY,
NAME VARCHAR(60)
)
CREATE TABLE Dog
(
CHIP_ID INT PRIMARY KEY,
OWNER_ID INT,
FOREIGN KEY(OWNER_ID) REFERENCES Person(ID)
)
I'm talking of course about the foreign key, I'm not sure if I have to specify it is a foreign key or not.
Thank you.
Yes, the DBMS see both as the same. But humans can many times miss important details when the code is cryptic. In fact, my preference is this:
CREATE TABLE Person(
ID INT not null,
Name VARCHAR(60) not null,
constraint PK_Person primary key( ID )
);
CREATE TABLE Dog(
ID INT not null,
OwnerID INT,
constraint PK_Dog primary key( CHIP_ID ),
constraint FK_Dog_Owner foreign key( OWNER_ID ) REFERENCES Person( ID )
);
Using the constraint clause not only defines the primary and foreign keys, but allow us to give them a meaningful name. And the surrogate key of each table should be named "ID". Any foreign keys in other tables will expand that name according to its context (RoleID). As you have in the Dog table with OwnerID. Another table with a FK to the same Person table may name it GroomerID or whatever else shows the role that person plays in the context of the table.
Also, as you can see, I prefer CamelCase with SQL Server, leaving OWNER_ID for Oracle.
Some even go so far as to place either NULL or NOT NULL after each column definition. But I find that adds clutter and doesn't really supply information even a beginning SQL developer doesn't already know. So I only supply NOT NULL when appropriate and let the default carry. Actually, in the later versions of Oracle and SQL Server, the NOT NULL for the primary key field is optional as the primary key is going to be defined as NOT NULL no matter what.
Long ago there seemed to be an informal contest to see who could cram the most operations into the fewest words or even characters. Just stay far away from that kind of thinking. But do make everything you write meaningful.
In general, use every opportunity to add meaningful information to the code. The computer doesn't care. Write to the other developers who will follow you.
Both T-SQL will create the foreign key you need. However, I believe the second approach where the code explicitely states "FOREIGN KEY..." is a good contribution to keep easy-maintenance and clean code for future software engineer understanding.
I'm currently designing a database to be implemented in SQL Server. I created the following tables without problem:
CREATE TABLE [Client] (
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
[IsEnabled] BIT NOT NULL DEFAULT 1,
CONSTRAINT PK_TCASystem PRIMARY KEY CLUSTERED (
ClientId
)
);
CREATE TABLE [Configuration] (
[ConfigId] INT NOT NULL,
[ClientId] INT NOT NULL,
[Name] VARCHAR(45) NOT NULL,
CONSTRAINT PK_Configuration PRIMARY KEY CLUSTERED (
ConfigId, ClientId
),
CONSTRAINT "FK_SystemConfiguration" FOREIGN KEY
(
ClientId
) REFERENCES [Client] (
ClientId
)
);
However, when I tried to add this one:
CREATE TABLE [Mail] (
[MailId] INT NOT NULL,
[ConfigId] INT NOT NULL,
[Recipient] VARCHAR(500) NOT NULL,
[Sender] VARCHAR(50) NOT NULL,
[Subject] VARCHAR(250) NOT NULL,
[Message] TEXT NULL,
CONSTRAINT PK_Mail PRIMARY KEY CLUSTERED (
MailId, ConfigId
),
CONSTRAINT "FK_ConfigurationMail" FOREIGN KEY
(
ConfigId
) REFERENCES [Configuration] (
ConfigId
)
);
I got an error saying that There are no primary or candidate keys in the referenced table 'Configuration' that match the referencing column list in the foreign key 'FK_ConfigurationMail'. I believe this is because the constraint is trying to reference ConfigId, only one half of the composite key, and for this to work I'd need to reference the ClientId too, is that correct?
But my problem is that I first did the design for this database in MYSQL Workbench, and there I indicated that Configuration and Mail, as well as Client and Configuration, have a 1:n identifying relationship (because a Mail instance cannot be created if there isn't a Configuration instance first, and at the same time a Configuration instance cannot exist without having being assigned to a Client first), and as such it created the composite keys for Configuration and Mail. You can see a picture of that here.
So my question is, how can I translate this identifying relationship to SQL Server? Or is that not possible?
EDIT: As suggested I will remove the composite keys from the Configuration table, albeit my question still stands: If I have a 1:n identifying relationship where one of the tables involved uses composite keys, how can I display this on SQL Server? Or is such a case never supposed to happen?
2ND EDIT: To anyone who might come across this question, this post is well worth a read. Cleared up all my confusion in the matter.
Foreign key must reference PK (the entire PK, not portion of PK) or unique index. So add this between create table [Configuration] and [Mail].
CREATE UNIQUE NONCLUSTERED INDEX [UX_Configuration] ON [Configuration]
(
[ConfigId] ASC
)
Check out at sql fiddle for the whole working script:
http://www.sqlfiddle.com/#!3/8877f
I am wondering does length of a primary key have a non-trivial effect on performance. For example consider the following table definitions,
CREATE TABLE table1 (
id VARCHAR(50) PRIMARY KEY,
first_column VARCHAR(50) NULL,
second_column VARCHAR(75) NOT NULL
);
CREATE TABLE table2(
id VARCHAR(250) PRIMARY KEY,
first_column VARCHAR(50) NULL,
second_column VARCHAR(75) NOT NULL
);
Does table1 performs better than table2, why?
In general, performance will depend more on what is stored than on the length of a varchar column. If both the varchar(50) and varchar(250) columns have a median length of 40 characters, they'll probably have similar performance.
In some dbms, the primary key is also a clustered key by default. But if your primary key is unsuitable as a clustered key, you can usually tell the dbms to not use a clustered key.
yes the primary key with varchar(50) will be more efficient. as You know the primary key holds Clustered Index on it, and as soon as new record is entered in the table, the value will be arranged in clustered index internally. You will see this difference in billions of records.
so its generally advised to have a natural primary key. Like id's etc.