Best data structure for full text search in SQL Server 2014 - sql-server

The following is a contrived simplified example:
USE Test;
IF OBJECT_ID('dbo.Books', 'U') IS NOT NULL
DROP TABLE dbo.Books;
IF OBJECT_ID('dbo.Authors', 'U') IS NOT NULL
DROP TABLE dbo.Authors;
CREATE TABLE dbo.Authors
(
AuthorId BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1),
AuthorName NVARCHAR(MAX) NOT NULL
)
CREATE TABLE dbo.Books
(
BookId BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1),
BookTitle NVARCHAR(MAX) NOT NULL,
FirstAuthorId BIGINT NOT NULL,
CONSTRAINT [FK_BookToFirstAuthor_Authors] FOREIGN KEY([FirstAuthorId]) REFERENCES Authors([AuthorId])
)
Would this be an efficient enough structure to full text search (e.g. via CONTAINS) in BookTitle and (First)AuthorName?
Or would something like this be better:
CREATE TABLE Books
(
BookId BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1),
BookTitle NVARCHAR(MAX) NOT NULL,
FirstAuthorId BIGINT NOT NULL,
FirstAuthorName NVARCHAR(MAX) NOT NULL,
CONSTRAINT [FK_BookToFirstAuthor_Authors] FOREIGN KEY([FirstAuthorId]) REFERENCES Authors([AuthorId])
)
Please note that I see Book rows like immutable 'objects'. Any feedback would be very much appreciated. Many thanks.

Related

Foreign key reference mismatched data type error

The ArtistID column in Piece table refers to the ArtistID in the Artist table. Likewise, the LocationID column in Piece refers to LocationID in the GeographicLocation table. However, both foreign key references throw a "not the same data type as referencing column" error. What am I doing wrong?
CREATE TABLE dbo.Artist
(
ArtistID SMALLINT PRIMARY KEY IDENTITY,
LastName VARCHAR(50) NOT NULL,
FirstName VARCHAR(40) NOT NULL,
Nationality VARCHAR(10) NULL,
BirthYear SMALLINT NOT NULL CHECK(BirthYear <= 1980),
DeathYear SMALLINT NULL,
Sex CHAR(1) NOT NULL CHECK(Sex = 'F' OR Sex = 'M')
)
CREATE TABLE dbo.Piece
(
PieceID SMALLINT PRIMARY KEY IDENTITY(1, 5),
ArtistID SMALLINT NOT NULL
FOREIGN KEY REFERENCES Artist(ArtistID),
LocationID SMALLINT NOT NULL
FOREIGN KEY REFERENCES GeographicLocation(LocationID),
CommonName VARCHAR(100) NULL,
YearProduced TINYINT NULL,
Period VARCHAR(50) NULL,
Medium VARCHAR(35) NOT NULL,
Frame VARCHAR(35) NULL,
AppraisedValue MONEY NOT NULL,
AppraiserID SMALLINT NOT NULL
FOREIGN KEY REFERENCES Appraiser(AppraiserID)
)
CREATE TABLE dbo.GeographicLocation
(
LocationID SMALLINT PRIMARY KEY IDENTITY,
Country VARCHAR(25) NOT NULL,
City VARCHAR(50) NOT NULL
)
I think you missed a table here, which is AppraiserID column in Piece table refers to the AppraiserID in the Appraisertable
So, when I execute your SQL I am getting below error:
Foreign key 'FK__Piece__Appraiser__322C6448' references invalid table 'Appraiser'.
First Create a table called Appraiser, then create Foreign key references for those column.
Below SQL I am able to create all tables and Foreign key references:
CREATE TABLE dbo.Artist
(ArtistID SMALLINT PRIMARY KEY IDENTITY,
LastName VARCHAR(50) NOT NULL,
FirstName VARCHAR(40) NOT NULL,
Nationality VARCHAR(10) NULL,
BirthYear SMALLINT NOT NULL CHECK(BirthYear <= 1980),
DeathYear SMALLINT NULL,
Gender CHAR(1) NOT NULL CHECK(Gender = 'F' OR Gender = 'M'))
CREATE TABLE dbo.GeographicLocation
(LocationID SMALLINT PRIMARY KEY IDENTITY,
Country VARCHAR(25) NOT NULL,
City VARCHAR(50) NOT NULL)
CREATE TABLE dbo.Appraiser
(AppraiserID SMALLINT PRIMARY KEY IDENTITY(1, 5),
AppraisedValue MONEY NOT NULL,
AppraisedName VARCHAR(100) NULL)
CREATE TABLE dbo.Piece
(PieceID SMALLINT PRIMARY KEY IDENTITY(1, 5),
ArtistID SMALLINT NOT NULL,
LocationID SMALLINT NOT NULL,
CommonName VARCHAR(100) NULL,
YearProduced TINYINT NULL,
Period VARCHAR(50) NULL,
Medium VARCHAR(35) NOT NULL,
Frame VARCHAR(35) NULL,
AppraisedValue MONEY NOT NULL,
AppraiserID SMALLINT NOT NULL)
ALTER TABLE dbo.Piece WITH CHECK ADD CONSTRAINT FK_Piece_ArtistID FOREIGN KEY(ArtistID)
REFERENCES dbo.Artist (ArtistID)
GO
ALTER TABLE dbo.Piece CHECK CONSTRAINT FK_Piece_ArtistID
GO
ALTER TABLE dbo.Piece WITH CHECK ADD CONSTRAINT FK_Piece_AppraiserID FOREIGN KEY(AppraiserID)
REFERENCES dbo.Appraiser (AppraiserID)
GO
ALTER TABLE dbo.Piece CHECK CONSTRAINT FK_Piece_AppraiserID
GO
ALTER TABLE dbo.Piece WITH CHECK ADD CONSTRAINT FK_Piece_LocationID FOREIGN KEY(LocationID)
REFERENCES dbo.GeographicLocation (LocationID)
GO
ALTER TABLE dbo.Piece CHECK CONSTRAINT FK_Piece_LocationID
GO

Creting FOREIGN KEY constraint on multiple columns with one of them being constant value

When I have table with PRIMARY KEY from 2 columns:
CREATE TABLE SizeTypes
(
TypeID tinyint NOT NULL,
SizeID tinyint NOT NULL,
Name varchar(100) NOT NULL,
CONSTRAINT PK_SizeType
PRIMARY KEY (TypeID, SizeID)
)
How can I create second table with a foreign key that have 1st constant value and 2nd from column like below:
CREATE TABLE Something
(
ID INT IDENTITY(1,1) PRIMARY KEY,
SizeTypeID_1 TINYINT,
SizeTypeID_2 TINYINT,
SizeTypeID_3 TINYINT,
CONSTRAINT FK_Something_SizeTypes_1
FOREIGN KEY (1, SizeTypeID_1)
REFERENCES SizeTypes(TypeID, SizeID),
CONSTRAINT FK_Something_SizeTypes_2
FOREIGN KEY (2, SizeTypeID_2)
REFERENCES SizeTypes(TypeID, SizeID),
CONSTRAINT FK_Something_SizeTypes_3
FOREIGN KEY (3, SizeTypeID_3)
REFERENCES SizeTypes(TypeID, SizeID)
)
This can be done using FOREIGN KEY, if yes then how?
If no then what other ways to do this I have? Triggers on INSERT and UPDATE for table something and on DELETE for table SizeTypes? Any other choices I have?
It looks like the following code will let you create suitable check constraints with the check implemented by a separate function:
-- Create the first table.
create table SizeTypes(
TypeId TinyInt not NULL,
SizeId TinyInt not NULL,
Name VarChar(100) not NULL,
constraint PK_SizeType primary key ( TypeId, SizeId ) );
go
-- Create a function to implement the logic for the check constraint.
create function CheckSizeTypeId(
#TypeId TinyInt, #SizeId TinyInt )
returns Int
as begin
-- Replace the following statement with the logic for your check.
if #SizeId >= 0 and #SizeId <= ( select SizeId from SizeTypes where TypeID = #TypeID )
return 1;
return 0;
end;
go
-- Create the second table with the check constraints.
create table Something(
Id Int identity(1,1) primary key,
SizeTypeId_1 TinyInt,
SizeTypeId_2 TinyInt,
SizeTypeId_3 TinyInt,
constraint Check_SizeTypeId_1 check ( dbo.CheckSizeTypeId( 1, SizeTypeId_1 ) = 1 ),
constraint Check_SizeTypeId_2 check ( dbo.CheckSizeTypeId( 2, SizeTypeId_2 ) = 1 ),
constraint Check_SizeTypeId_3 check ( dbo.CheckSizeTypeId( 3, SizeTypeId_3 ) = 1 ) );
go
-- Houseclean.
drop table SizeTypes;
drop table Something;
drop function CheckSizeTypeId;
Note that the constraints restrict what you can do with values in Something. Changes in SizeTypes will not revalidate data in Something, though that could be implemented in a trigger on SizeTypes.

Using the last inserted record's ID as a foreign key

I am making a database which links together two tables via the primary key of the first table. The one with the primary key which links the two is created first but how do i make the second record get the ID of the record I just created?
create table Person
(
Person_ID int IDENTITY(100000,1) primary key,
First_Name varchar(20) not null,
Last_Name varchar(20) not null,
)
create table Employee
(
Employee_ID int identity(100000,1) primary key,
Person_ID int references Person(Person_ID),
Employee_Type varchar(10)
)
insert into Person(First_Name, Last_Name) values ('Michael', 'Chu');
insert into Employee(Person_ID, Employee_Type,) values (????????, 'Admin');
I've had a look at the 'last()' function but not really sure how to utilise that. Other then that, I have no idea. Can someone help me out or guide me in the right direction.
try this:
create table Person
(
Person_ID int IDENTITY(100000,1) primary key,
First_Name varchar(20) not null,
Last_Name varchar(20) not null,
)
create table Employee
(
Employee_ID int identity(100000,1) primary key,
Person_ID int references Person(Person_ID),
Employee_Type varchar(10)
)
DECLARE #myID AS INT
insert into Person(First_Name, Last_Name) values ('Michael', 'Chu');
SET #myID = ##IDENTITY
insert into Employee(Person_ID, Employee_Type,) values (#myID , 'Admin');

How to create a reference key from given details

Create table test1
(
id bigint Not Null,
name varchar(10) Not Null
constraint pk_test primary key(id,name)
)
Create table test2
(
Mid bigint Not Null references test1(id) ,
MSalary varchar(10) Not Null
)
In test2 I am not able to create a reference to test1 id Please help me..
Thanks in Advance!!!!
You need a foreign key in order to reference a table. Try this:
CREATE TABLE test1
(
id bigint NOT NULL PRIMARY KEY,
name varchat(10) NOT NULL
)
CREATE TABLE test2
(
Mid bigint NOT NULL,
MSalary varchar(10) NOT NULL,
FOREIGN KEY (Mid) REFERENCES test1(id)
)

What is the proper procedure when trying to test your database in SQL?

I'm pretty new to databases and I have this assignment that I've completed where I had to look at a merged Entity Relationship Diagram and then create Drop Tables, Tables (with constraints and identity's), Alterations and Indexes. I'm pretty sure I've coded everything correctly but the only area I'm a little unsure about, it's how to test that the database will actually function when executing it. My instructor gave me a TestData.sql file that I just have to refer to the database and then execute and it should insert all the data into the tables and drop everything correctly. I have it all hooked up properly on SQL Server Management Studio but I forget what steps I should be taking in order to test the proper execution of the tables. I'll post some of my code so you guys can take a look. Any information regarding this issue would be greatly appreciated!
Also, when it says in the Test Data SQL code "IMPORTANT! If you need to run this script more than once you must drop and recreate your tables first to reset the identity properties." --Does this mean that if I run into any errors while trying to execute the test data, I will have to execute the DROP TABLES first and then maybe copy and paste all the TABLES back into the Database file? I don't actually have to manually type all the TABLES again, just need to re-enter them as "new" so the system will kind of reset it's identity properties?
If you guys need me to post more of the code for clarification, just let me know. Thanks for taking the time to read this :)
Update: I'm getting 2 error messages when trying to execute the TestData script: "Invalid object name 'SaleDetail'." and "Invalid object name 'Author'." I've also provided the rest of the code from my Database script file for you to take a look at. I'm almost certain everything is correct.
Database Tables Code (this is the complete code script)
USE Lab2A_BooksGalore
GO
/*------ Drop Table Statements ------*/
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'SaleDetail')
DROP TABLE SaleDetail
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'AuthorTitle')
DROP TABLE AuthorTitle
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Title')
DROP TABLE Title
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Publisher')
DROP TABLE Publisher
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Category')
DROP TABLE Category
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Author')
DROP TABLE Author
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Sale')
DROP TABLE Sale
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Employee')
DROP TABLE Employee
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Customer')
DROP TABLE Customer
/*------- Create Table Statements -------*/
CREATE TABLE Customer
(
CustomerNumber int
CONSTRAINT PK_Customer_CustomerNumber
PRIMARY KEY
IDENTITY (1, 1) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
[Address] varchar(40) NULL,
City varchar(30) NULL,
Province char(2)
CONSTRAINT DF_Customer_Province
DEFAULT ('AB') NULL,
PostalCode char(6)
CONSTRAINT CK_Customer_PostalCode
CHECK (PostalCode LIKE '[A-Z][0-9][A-Z][0-9][A-Z][0-9]')
NULL,
HomePhone char(10)
)
CREATE TABLE Employee
(
EmployeeNumber int
CONSTRAINT PK_Employee_EmployeeNumber
PRIMARY KEY
IDENTITY (300, 1) NOT NULL,
[SIN] char(9) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
[Address] varchar(40) NULL,
City varchar(20) NULL,
Province char(2)
CONSTRAINT DF_Employee_Province
DEFAULT ('AB') NULL,
PostalCode char(6)
CONSTRAINT CK_Employee_PostalCode
CHECK (PostalCode LIKE '[A-Z][0-9][A-Z][0-9][A-Z][0-9]')
NULL,
HomePhone char(10) NULL,
WorkPhone char(10) NULL,
Email varchar(40) NULL,
)
CREATE TABLE Sale
(
SaleNumber int
CONSTRAINT PK_Sale_SaleNumber
PRIMARY KEY
IDENTITY (3000, 1) NOT NULL,
SaleDate datetime NOT NULL,
CustomerNumber int
CONSTRAINT FK_Sale_CustomerNumber_Customer_CustomerNumber
FOREIGN KEY REFERENCES Customer(CustomerNumber)
NOT NULL,
EmployeeNumber int
CONSTRAINT FK_Sale_EmployeeNumber_Employee_EmployeeNumber
FOREIGN KEY REFERENCES Employee(EmployeeNumber)
NOT NULL,
Subtotal money
CONSTRAINT CK_Sale_Subtotal
CHECK (Subtotal <= Total) NOT NULL,
GST money NOT NULL,
Total money
CONSTRAINT CK_Sale_Total
CHECK (Total >= Subtotal) NOT NULL,
)
CREATE TABLE Author
(
AuthorCode int
CONSTRAINT PK_Author_AuthorCode
PRIMARY KEY
IDENTITY (100, 1) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
)
CREATE TABLE Category
(
CategoryCode int
CONSTRAINT PK_Category_CategoryCode
PRIMARY KEY
IDENTITY (1, 1) NOT NULL,
[Description] varchar(40) NOT NULL,
)
CREATE TABLE Publisher
(
PublisherCode int
CONSTRAINT PK_Publisher_PublisherCode
PRIMARY KEY
IDENTITY (200, 1) NOT NULL,
[Name] varchar(40) NOT NULL,
)
CREATE TABLE Title
(
ISBN char(10)
CONSTRAINT PK_Title_ISBN
PRIMARY KEY NOT NULL,
Title varchar(40) NOT NULL,
SuggestedPrice smallmoney
CONSTRAINT DF_Title_SuggestedPrice
DEFAULT (0) NOT NULL,
NumberInStock smallint
CONSTRAINT CK_Title_NumberInStock
CHECK (NumberInStock >= 0)
CONSTRAINT DF_Title_NumberInStock
DEFAULT (0) NOT NULL,
PublisherCode int
CONSTRAINT FK_Title_PublisherCode_Publisher_PublisherCode
FOREIGN KEY REFERENCES Publisher(PublisherCode)
NOT NULL,
CategoryCode int
CONSTRAINT FK_Title_CategoryCode_Category_CategoryCode
FOREIGN KEY REFERENCES Category(CategoryCode)
NOT NULL,
)
CREATE TABLE AuthorTitle
(
ISBN char(10)
CONSTRAINT FK_AuthorTitle_ISBN_Title_ISBN
FOREIGN KEY REFERENCES Title(ISBN)
NOT NULL,
AuthorCode int
CONSTRAINT FK_AuthorTitle_AuthorCode_Author_AuthorCode
FOREIGN KEY REFERENCES Author(AuthorCode)
NOT NULL,
)
CREATE TABLE SaleDetail
(
SaleNumber int
CONSTRAINT FK_SaleDetail_SaleNumber_Sale_SaleNumber
FOREIGN KEY REFERENCES Sale(SaleNumber)
NOT NULL,
ISBN char(10)
CONSTRAINT FK_SaleDetail_ISBN_Title_ISBN
FOREIGN KEY REFERENCES Title(ISBN)
NOT NULL,
SellingPrice money NOT NULL,
Quantity int NOT NULL,
Amount money NOT NULL,
)
/*----------------- Alter Table Statements --------------------*/
---1) Add a char(10) attribute named WorkPhone to the Customer Table
ALTER TABLE Customer
ADD WorkPhone char(10) NULL
GO
---2) Add a varchar(30) attribute named Email to the Customer Table
ALTER TABLE Customer
ADD Email varchar(30) NULL
GO
---3) Add a constraint to make sure the correct format is followed for the Email attribute
ALTER TABLE Customer
ADD CONSTRAINT CK_Customer_Email
CHECK (Email LIKE '[a-z, 0-9][a-z, 0-9][a-z, 0-9]%#[a-z, 0-9][a-z, 0-9][a-z, 0-9]%.[a-z, 0-9][a-z, 0-9]%')
--- Match For: b 8 l # g v t . c a
GO
---4) Add a char(1) attribute named Active that's required for the Employee Table
ALTER TABLE Employee
ADD Active char(1) NOT NULL
GO
---5) Add a constraint to make sure the default character is used for the Active attribute
ALTER TABLE Employee
ADD CONSTRAINT DF_Employee_Active
DEFAULT ('y')
GO
/*------------------ Foreign Key Index Statements -----------------*/
CREATE NONCLUSTERED INDEX IX_Sale_CustomerNumber
ON Sale (CustomerNumber)
CREATE NONCLUSTERED INDEX IX_Sale_EmployeeNumber
ON Sale (EmployeeNumber)
CREATE NONCLUSTERED INDEX IX_Title_PublisherCode
ON Title (PublisherCode)
CREATE NONCLUSTERED INDEX IX_Title_CategoryCody
ON Title (CategoryCode)
CREATE NONCLUSTERED INDEX IX_AuthorTitle_ISBN
ON AuthorTitle (ISBN)
CREATE NONCLUSTERED INDEX IX_AuthorTitle_AuthorCode
ON AuthorTitle (AuthorCode)
CREATE NONCLUSTERED INDEX IX_SaleDetail_SaleNumber
ON SaleDetail (SaleNumber)
CREATE NONCLUSTERED INDEX IX_SaleDetail_ISBN
ON SaleDetail (ISBN)
GO
Test Data Code(this is only a snippet being this script is 100% accurate - provided by instructor)
USE Lab2A_BooksGalore
GO
--Lab 2 insert script
--IMPORTANT! If you need to run this script more than once you must drop and recreate your tables first to reset the identity properties.
--Delete existing data in the tables, if there is any
Delete From SaleDetail
Delete From Sale
Delete From AuthorTitle
Delete From Title
Delete From Employee
Delete From Customer
Delete From Category
Delete From Publisher
Delete From Author
Go
Insert into Author
(LastName, FirstName)
Values
('Smith', 'Sammy'),
('Greens', 'George'),
('Jones', 'Johnny'),
('Davidson', 'David'),
('Robertson', 'Rob'),
('Abbots', 'Abe'),
('Bakers', 'Bob'),
('Caters', 'Clem'),
('Semenko', 'Dave'),
('Franky', 'Fran'),
('Horton', 'Harry'),
('Kelly', 'Kevin'),
('Lambert', 'Larry'),
('Johnson', 'Jon'),
('Anderson', 'Ander'),
('Peterson', 'Peter'),
('Jensen', 'Jens'),
('Issacsen', 'Issac')
Insert into Publisher
(Name)
Values
('Addison Westley'),
('SAMS'),
('Harlequin'),
('Self Publish Inc'),
('Microsoft Press'),
('Jones and Bartlett'),
('WROX'),
('West'),
('Premier')
Insert into Category
(Description)
Values
('Computers'),
('Business'),
('Human Relation'),
('Electronics'),
('Designs'),
('Miscellaneous'),
('Media Design'),
('Information Technologies')

Resources