SQL Server - Unique index vs Unique constraint - Re. Duplicate values - sql-server

A unique index ensures that the values in the index key columns are unique.
A unique constraint guarantees that no duplicate values can be inserted into the column(s) on which the constraint is created. When a unique constraint is created a corresponding unique index is automatically created on the column(s).
Qusetions:
Can duplicate values be inserted if we have a unique index on a column and no unique constraint?
What about existing duplicates in any on the column - will it allow to create unique index or unique constraint?

Can duplicate values be inserted if we have a unique index on a column
and no unique constraint?
Generally, duplicate values cannot be inserted and an error is raised when a unique index exists on the column. The exceptions are:
Index was created with the IGNORE_DUP_KEY option. No error is raised and the insert is ignored.
The non-clustered index is filtered such that the duplicate value does not satisfy the index WHERE clause. The row is inserted but not reflected in the non-clustered index.
What about existing duplicates in any on the column - will it allow to
create unique index or unique constraint?
No, with the exception of the filtered index mentioned above.

Can duplicate values be inserted if we have a unique index on a column and no unique constraint?
No, the values of the columns within the index must create a unique set of data within that index.
What about existing duplicates in any on the column - will it allow to create unique index or unique constraint?
No, you cannot create a Unique Index on a table that has duplicate values.
This easiest way to have found this out would be to try (I suggest for things like that doing so, it's a great way of learning):
CREATE TABLE dbo.SomeTable (SomeInt int, AnotherInt int);
GO
INSERT INTO dbo.SomeTable (SomeInt,
AnotherInt)
VALUES (1,1),
(1,2),
(2,1);
GO
--Create a unique index on a column with duplicate values
CREATE UNIQUE INDEX UQ_SomeInt ON dbo.SomeTable(SomeInt); --fails
GO
--Create a unique index on the 2 columns, as they are unique
CREATE UNIQUE INDEX UQ_Some_AnotherInt ON dbo.SomeTable(SomeInt, AnotherInt); --Succeeds
GO
--Try to insert a duplicate value
INSERT INTO dbo.SomeTable (SomeInt,
AnotherInt)
VALUES(2,1); --fails
GO
SELECT *
FROM dbo.SomeTable
GO
DROP TABLE dbo.SomeTable;

One potentially unintuitive scenario that confused me at first: postgres does not treat NULL values as equal. If your table looked like this:
+-------+-------+-------+
|id |a |b |
+-------+-------+-------+
|1 |0 |NULL |
|2 |0 |NULL |
+-------+-------+-------+
You could still add a unique index on columns a and b. According to Postgres, row with id 1 and row with id 2 have the same value for column a, but different values for column b

Related

insert rows to table with PRIMARY KEY from different tables without PRIMARY KEY sql server

I hope to explain very well my problem
I have a new table with a Primary Key.
How to insert the table from different tables?
my problem is the one table without Primary Key and I don't know how to select from table one row and insert to the new table.
Example -
new table 1
image
AssetId is Primary key
table 2
image
I need to insert one row to table 1
table 3 image
my script -
insert AssetBusStops (AssetId,StopCode,StopId,Description,ZoneId)
select Assets.Id,stops_ppp.stop_code,stops_ppp.stop_id,stops_ppp.stop_desc,stops_ppp.zone_id from Assets inner join stops_ppp
on Assets.AssetCode = stops_ppp.stop_code
Exception -
Msg 2627, Level 14, State 1, Line 11
Violation of PRIMARY KEY constraint 'PK_AssetBusStops'. Cannot insert duplicate key in object 'dbo.AssetBusStops'. The duplicate key value is (2763).
The statement has been terminated.
The value 20001 of the column AssetCode of the table Assets matches 3 rows from the table stops_ppp and these 3 rows in the result joined query have the same value 2763 in the column id.
So your query tries to insert 3 rows, not just 1 and this would create duplicates in the primary key, which is not allowed.
You should apply a filter in the results of the query, something like:
insert AssetBusStops (AssetId,StopCode,StopId,Description,ZoneId)
select top 1 ASsets.Id,
stops_ppp.stop_code, stops_ppp.stop_id, stops_ppp.stop_desc, stops_ppp.zone_id
from Assets inner join stops_ppp
on Assets.AssetCode = stops_ppp.stop_code
order by stops_ppp.stop_code
This (for your sample data) returns only 1 row (an arbitrary ow as you requested in the comments) and can be safely inserted.
A) If you don't have FK to table AssetBusStops :
Change PK Column to IDENTITY(1,1)
Remove PK value from Insert script
B) If you have FK to table AssetBusStops :
try to use Not Exists or Merge

how to define full text searching on table with two keys?

I have a table with 2 columns as primary key like below.
create table table1(key1 int NOT NULL,key2 int NOT NULL,content NVARCHAR(MAX), primary key(key1,key2))
I have created index on table with this query
CREATE unique INDEX index1 ON table1 (key1,key2);
and with this query, I create full-text searching
create fulltext index on table1 (content ) key index index1;
but I get this error because index must be single-column
'index1' is not a valid index to enforce a full-text search key. A full-text search key must be a unique, non-nullable, single-column index which is not offline, is not defined on a non-deterministic or imprecise nonpersisted computed column, does not have a filter, and has maximum size of 900 bytes. Choose another index for the full-text key.
and with single Column indexing, when I insert a new row I get a duplicate error.
what should I do?
I am using SQL Server and EF orm
Update
i solve this problem by creating a computed column that return unique data
ALTER TABLE Table1 ADD indexKey AS cast(key1 as float) + cast((cast(key2 as float)/power(10,len(key2))) as float) PERSISTED not null
and i create my index on this column and it work pretty fine.

SQL SERVER: Unique Constraint Explanation

Could someone simplify the explanation of adding a UNIQUE CONSTRAINT to a column please.
When creating the key index does SQL SERVER copy ALL of the information in the row and add it to the index or just the data in the column with the applied UNIQUE CONSTRAINT?
I hope I explained that properly.
Any help will be greatly appreciated.
Lee.
EDIT**
Ok i think i get it?
CREATE TABLE dbo.test
(
Id int NOT NULL,
Name char(10) NOT NULL UNIQUE
);
INSERT INTO dbo.test (id, name) VALUES (1, 'Lee')
INSERT INTO dbo.test (id, name) VALUES (2, 'Paul')
INSERT INTO dbo.test (id, name) VALUES (3, 'Adam')
INSERT INTO dbo.test (id, name) VALUES (4, 'Henry')
In a clustered index the whole table would be sorted like
3, Adam
4, Henry
1, Lee
2, Paul
So with each additional INSERT the server would have to re-sort the entire table based on the name column?
In a nonclustered index there is another "table" that stores the sort?
When creating the key index does SQL SERVER copy ALL of the
information in the row and add it to the index or just the data in the
column with the applied UNIQUE CONSTRAINT?
There is no such a term as "key index".
Indexes can be clustered or non-clustered.
When you declare UNIQUE CONSTRAINT it's logical entity, but it's physically supported by unique index creation
When you create your unique constraint declaring it as clustered, clustered index will be created. If you don't mention clustered in your constraint definition or use explicite nonclustered, non-clustered index will be created.
Non-clustered index is a separate data structure where every row contains key columns.
On the other hand, clustered index (or better call it clustered table) is data itself + searching B-tree above it. In this case no separate structure is created, it's table itself that now is organized not as a heap but as ordered index.
UNIQUE CONSTRAINT will work just as UNIQUE INDEX. There are 2 ways:
With a clustered index the rows are stored physically on the disk in the same order as the index. (hence, only one clustered index is possible)
With a non clustered index there is a second list that has pointers to the physical rows. You can have many non clustered indexes, although each new index will increase the time it takes to write new records.
If you have both clustered and non clustered index, then non clustered index will point to the clustered index column.
THIS 'SO' answer will help you understand it a bit clear.
By default the unique constraint and Unique index will create a non
clustered index if you don't specify any different (and the PK will by
default be created as CLUSTERED if no conflicting clustered index
exists) but you can explicitly specify CLUSTERED/NONCLUSTERED for any
of them.

SQL Index Identity Column Sort Order

I have a transaction table:
|rowID|value1|value2|...|
|11111|12 |34 |...|
|11112|23 |123 |...|
|11113|99 |53 |...|
...
RowID is the Identity and increments by 1. Indexing is also no problem. Lots of new values get inserted, updates happen and sometimes some rows may get deleted.
But now I have a second table:
|rowID|flag1|flag2|...|
|11113|0 |1 |...|
|11111|1 |1 |...|
|11112|0 |1 |...|
...
It is a user operation, which inserts rows from the transaction table into this second table. RowID corresponds to RowID from the transaction table.
The insert to the second table are not sorted by the RowID. A higher RowID may be inserted earlier, than a lower RowID.
What is the best indexing strategy for such a table?
Is it wise to define RowID in the second table as primary key, resulting in a clustered index? Which, I think, is not ideal because the RowID's are not sorted.
Is it better to have no primary key, but a suitable non-clustered index?
I wonder if there are some general advise for such a table (second table)?
Tables are not ordered dataset. The fact RowID isnt order on the second table doesnt matter at the moment of define PK/index.
You should make RowID the PK for Table2 The moment the index is created a B-TREE is also created and the data is stored there for fastest access.

How to update column with unique key constraint?

I've inserted several rows into a table, using duplicates in a column (theId) with a unique key constraint. I did this by setting IDENTITY_INSERT to off then on.
I tried this same technique to update, since I need to change those dupe values but it isn't working:
SET IDENTITY_INSERT mytable OFF
update mytable set
theId = 5
WHERE mytableId in (40, 41)
SET IDENTITY_INSERT mytable ON
Error:
Violation of UNIQUE KEY constraint 'XI_mytale_mytableId_othercolumn_U'. Cannot insert duplicate key in object 'dbo.mytable'.
Any ideas how this can be done with an UPDATE?
I think you are confusing with An Identity Column where you managed to add values manually after Setting SET IDENTITY_INSERT mytable ON; with a Column with Unique Constraint Defined on it. A column with Unique Constraint will never allow you to add duplicate values.
If you do want to be able to add Duplicate values in a column with a unique constraint you can simple drop the unique constraint as why have a unique constraint when you dont have unique values.
You can droo the Unique Constraint using following statement,
ALTER TABLE TableName
DROP CONSTRAINT uc_ConstraintName

Resources