I am trying to create a SQL table to store a customer id and zipcode, only these 2 columns. Combination of these 2 values makes a row unique. I have 3 options in mind but not sure which one would be efficient. I will store around 200000 rows in this table and the read operation is high and write will happen once in a day.
Select query will get all customers based on the input zipcode.
example:
Select customerid from dbo.customerzipcode where zipcode in (<multiple zipcodes>)
Option 1:
Create a table with 2 columns (customerid and zipcode)
Create a composite primary key for these 2 columns.
Option 2:
Create a table with 3 columns (id, customerid and zipcode)
id being identity and primary key
create a unique constraint for customerid and zipcode
Option 3:
Create a table with 3 columns (id, customerid and zipcode)
Create a non clustered index for zipcode alone.
Can you please share which option would be better?
Select customerid from dbo.customerzipcode where zipcode in ()
The canonical design would have an index with each column as the leading column to support efficient lookup by zipcode or by customerid, eg
create table customerzipcode
(
zipcode varchar(10) not null,
customerid int not null references customer,
constraint pk_customerzipcode primary key (zipcode,customerid),
index ix_customerzip_customerid (customerid)
)
Related
I want to know what is the most optimized data structure:
I have 2 tables like:
CREATE TABLE Person
(
Id Int NOT NULL PRIMARY KEY,
name varchar(50)
)
CREATE TABLE Group
(
Id Int NOT NULL PRIMARY KEY,
nameOfGroup varchar(50)
)
In my table to connect persons to groups I want to know what is the most optimized way to create it between an ID and then the foreign keys, like that:
CREATE TABLE PersonGroup
(
Id Int DISTINCT NOT NULL PRIMARY KEY,
PersonId Int, -- which is a foreign key to table Person
GroupId Int -- which is a foreign key to table Group
)
OR having the 2 foreign keys as a primary because no one can be 2 times in the same group anyway, like that :
CREATE TABLE PersonGroup
(
PersonId Int NOT NULL, -- which is a foreign key to table Person
GroupId Int NOT NULL, -- which is a foreign key to table Group
CONSTRAINT PK_PersonSgroup PRIMARY KEY (PersonId, GroupId)
)
What is the most optimized between those 2 tables for querying after (if there is more optimize).
Thank you to have read my post.
The first solution (PK identity) is incomplete because you need to have an alternate (or surrogate) key (AK) compound of the two FK.
In the two possibilities, you must know that the order of the two FK in the PK or the AK is very important. This order must follow the usual querying way. So the questions are
do you use first the group then the person in queries ?
do you use first the personthen the group in queries ?
Also you need an index on the second PK, not the first of the PK or AK compound of the two PK.
For me the best table will be:
CREATE TABLE PersonGroup
(
PersonId Int NOT NULL REFERENCES Person (PersonId),
GroupId Int NOT NULL REFERENCES Group (GroupId),
CONSTRAINT PK_PersonSgroup PRIMARY KEY (PersonId, GroupId)
);
CREATE INDEX X_PersonGroup_FK_Group (GroupId);
What is the best way to generate Id or Code column(primary key) in a table in SQL Server? My requirement is a big table which stores more than 1000000 rows.
So generally we create auto identity column of a table but is it the best way? For example, I have an employee_master table and there are three columns like
emp_id auto increment
Emp_code varchar(20)
and also default like Rowno of a table.
So in this scenario, it has 3 unique columns of a table. Is it the best way?
Or what is the best way to generate id/code column both master and transaction table.
Also is there any way which we generate financial year wise auto-generate column.(any function)
The following SQL statement defines the "ID" column to be an auto-increment primary key field in the "Persons" table
CREATE TABLE Persons (
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (ID)
);
I think this will work..
I am creating a table Brands with the following schema :
UserId
CarId
Brand
The UserId references the id of an user in the user table
The CarId references the id of a car in the car table
The only query that I will use is a search bases on these 2 columns, to get the corresponding brand.
So my question was about the constraint part, as I am a beginner, I would like to know which type of constraint to use (index, primary key, clustered or non clustered, on each field or on the 2 fields together) to have my query the more optimized possible.
This is my script right now :
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Brands]') AND type in (N'U'))
BEGIN
CREATE TABLE [Brands]
(
UserId BIGINT NOT NULL
CONSTRAINT [FK_Brands_Users]
FOREIGN KEY REFERENCES [Users] (UserId),
CarId BIGINT NOT NULL
CONSTRAINT [FK_Brands_Cars]
FOREIGN KEY REFERENCES [Cars] (CarId),
Brand nvarchar(15),
);
END
GO
ALTER TABLE [Brands]
ADD CONSTRAINT [Unique_UserId_BrandId] UNIQUE(UserId, BrandId);
GO
I would create a primary key including both fields. When you define a primary key it automatically create a clustered index. Also your primary key has a unique constraint build in. Your table is now a heap the way you wrote it here above which is not good. You can additionally create an extra non-clustered index on CarId. Having an additional non-clustered index on UserId is not usefull I think. The column UserId can use the clustered index because it's the first field in the clustered index but I'm not sure about that.
Suppose I have two tables: A (with columns: a,b,c,d) and B (with columns: x,y,z). Now, (a,b) together make the primary key for table A and x is the primary key of table B. Is it possible to make b a foreign key of table A that refers x from table B?
Please reply ASAP!
Thanks in advance! :-)
Yes, there is no issue with that. A classic example (using MySQL for demonstration purposes) is a database table holding a number of companies and another holding employees which can work for any one of those companies:
create table companies (
id int primary key,
name varchar(20));
create table employees (
id int,
c_id varchar(20) references companies(id),
name varchar(20),
primary key (id, c_id));
insert into companies (id, name) values (1, 'ABC');
insert into companies (id, name) values (2, 'DEF');
insert into companies (id, name) values (3, 'HIJ');
insert into employees (id, c_id, name) values (101, 1, "Allan");
insert into employees (id, c_id, name) values (102, 1, "Bobby");
insert into employees (id, c_id, name) values (101, 2, "Carol");
insert into employees (id, c_id, name) values (101, 3, "David");
Note that the primary key for employees is a composite key made up of the employee ID and company ID. Note also that the company ID is a foreign key constraint on the primary key of companies, the exact situation (functionally) that you asked about.
The query showing who works for what company shows this in action:
select c.id, c.name, e.id, e.name
from companies c, employees e
where c.id = e.c_id
order by c.id, e.id
c.id c.name e.id e.name
---- ------ ---- ------
1 ABC 101 Allan
1 ABC 102 Bobby
2 DEF 101 Carol
3 HIJ 101 David
Can a column in a composite primary key also be a foreign key referencing a primary key of another table? Of course it can. The important question is, when is this a good idea?
The most common scenario is probably the intersection or junction table. Customers can have more than one Address (Shipping, Billing, etc) and Addresses can have more than one Customer using them. So the table CUSTOMER_ADDRESSES has a primary key which references both CUSTOMER and ADDRESS primary key (and for bonus points the ADDRESS_TYPE reference data table too).
My examples use Oracle 12c syntax:
create table customer_address
( customer_id number(38,0) not null
, address_id number(38,0) not null
, address_type_code varchar2(3) not null
, constraint customer_address_pk primary key
(customer_id, address_id, address_type_code)
, constraint customer_address_customer_fk foreign key
(customer_id) references customer(customer_id)
, constraint customer_address_address_fk foreign key
(address_id) references address(address_id)
, constraint customer_address_type_fk foreign key
(address_type_code) references address_type(address_type_code)
);
The second scenario occurs when the primary key of the child table is comprises the parent key and an identifier (usually a number) which is only unique within the parent key. For instance, an Order has an Order Header and some Order Lines. The Order is identified by the Order Header ID and its lines are identified by a monotonically incrementing number. The ORDER_LINE table may look like this:
create table order_line
( order_header_id number(38,0) not null
, order_line_no number(38,0) not null
, product_id number(38,0) not null
, qty number(38,0) not null
, constraint order_line_pk primary key
(order_header_id, order_line_no)
, constraint order_line_header_fk foreign key
(order_header_id) references order_header(order_header_id)
, constraint order_line_product_fk foreign key
(product_id) references product(product_id)
);
Note that we could model ORDER_LINE as another intersection table, with a primary key of (order_header_id, product_id) and relegate order_line_no to the status of ordinary attribute: it depends on the business rules we must represent.
This second scenario is rarer than you might think: composite primary keys are pretty rare in real life. For instance, I think the model presented in that other answer is weak. The chances are we will need to use Employee as a foreign key for a number of relationships (e.g. Manager, Assignment, Sales). Using a composite key for foreign keys is clumsy (more typing!). Furthermore, when we drill into these models we often find that one of the key columns is a natural key rather than a primary key, and so might be subject to change. Cascading changes to natural key columns in composite foreign keys is a PITN.
Hence it is common practice to use a surrogate (or synthetic) primary key, say using a sequence or identify column, and enforce the natural key with a unique constraint. The latter step is often forgotten but it is crucial to maintaining referential integrity. Given a situation in which we need to store details of Employees from several Companies, including the Companies' Employee Identifier we might have an EMPLOYEE table like this:
create table employee
( employee_id number(38,0) generated always as number
, company_id number(38,0) not null
, company_employee_id varchar2(128) not null
, name varchar2(128) not null
, constraint employee_pk primary key
(employee_id)
, constraint employee_uk unique
(company_id, company_employee_id)
, constraint employee_company_fk foreign key
(company_id) references company(company_id)
);
One situation where it is common to find composite primary keys cascaded to dependent tables is in data warehouses and other VLDBs. Here the composite key columns form part of a denormalization strategy to support Partitioning schemes and/or efficient access paths.
I'm having problems with adding another primary key to my table.
I have 3 columns:
Account ID (Identity)
EmailID
Data field
When I made the table I had this to make the Account ID and the Email ID unique.
PRIMARY KEY (AccountID, EmailID)
I thought that would make my emailid unique, but then after I tried inserting another row with the same emailid it went through.
So I thought I missed something out.
Now for my question:
IF, I had to use alter, how do I alter the table/PK Constraint to modify the EmailID field and make it Unique?
IF I decided to drop the table and made a new one, how do I make those two primary keys unique?
You may ALTER the table and add a new UNIQUE CONSTRAINT on the EmailID column.
-- This will create a constraint which enforces that the field EmailID
-- have unique values
ALTER TABLE Your_Table_Name
ADD CONSTRAINT unique_constraint_name UNIQUE (EmailID)
It's worth noting though, that altering the table to add this new unique constraint doesn't mean that you have to drop the other PRIMARY KEY constraint that you have added for the (AccountID, EmailID) pair. That is, of course, unless your business logic dictates it.
When you make the grouping of (AcountID, EmailID) the PRIMARY KEY it specifies that both the AcountID and EmailID participate in uniquely identifying each individual record in that table. So, that means that you could have the following records in the table:
AccountID | EmailID | Other Fields
----------------------------------------------------------
100 | user#company.com | ....
101 | user2#othermail.com | ....
100 | user_alternate#mail.com | ....
In the previous example it is possible to have two records with the same AccountID, and that is valid because the PRIMARY KEY specifies that only the (AccountID, EmailID) pair has to be unique - which it is. It makes no stipulation about AccountID being unique independently.
In conclusion, you probably want to add yet another UNIQUE constraint on AccountID. Or simply make the AccountID alone the PRIMARY KEY and then add a UNIQUE constraint on EmailID.
If both AccountID and EmailID are candidate keys then only one can be the PK the other one will need a unique constraint.
From the POV of SQL Server it doesn't matter which one you choose as the PK. Foreign Key's can reference either the PK or a unique constraint but given that the PK is the clustered index by default it probably makes sense to choose AccountID as this is presumably narrower and more stable.
It sounds like an incorrect Primary key. It's more likely that emailID is intended to be your natural key but for some reason (maybe a development standard in your organization?) you want to use a surrogate ID, AccountID but you still intend for both email ID and surrogate ID to both be unique and have a one to one relationship. If this is true then your primary key should be AccountID and you should place a unique constraint on EmailID.
If you were to recreate the table, it could look like this. I assumed EmailID was referencing an email table instead of being an email address.
CREATE TABLE dbo.AccountEmails
(
AccountID int not null identity(1,1),
EmailID int not null,
Data varchar(max) null,
constraint PK_AccountEmails PRIMARY KEY //this is a unique single column primary key
(
AccountID
),
constraint FK_AccountEmails_EmailID FOREIGN KEY dbo.Email(EmailID) ON //this makes sure EmailID exists in the Email table
(
EmailID
),
constraint UQ_AccountEmails_EmailID UNIQUE //unique single column unique constraint
(
EmailID
),
constraint UQ_AccountEmails_AccountID_EmailID UNIQUE //the combination of AccountID and EmailID is also unique
(
AccountID,
EmailID
)
)
Given the fact that AccountID and EmailID are both seperately unique, I'm not sure UQ_AccountEmails_AccountID_EmailID is really necessary.