On one of my tables in SQL Server, In the Indexes folder I have a Clustered Index made from three columns of that table but there is also a Unique checkbox when I go to properties window on that index.
My question is with T-SQL commands how I tell it to drop the Uniqueness part and still keep the index? Is it even possible?
You cannot alter index from unique to non-unique. You can set index to ignore duplicates.
Docs: https://msdn.microsoft.com/en-us/library/ms188388.aspx
You can only recreate index with drop and create commands.
DROP INDEX IndexTest.ci_Test;
CREATE INDEX ci_Test ON IndexTest(Key);
But you should have clustered index on one column (for example on new autoincrement primary key). And you can force uniqueness with unique non-clustered index.
Related
I am implementing functionality for a table that when an edit/change is made it will save a copy of the pre-edit row and mark it as is_deleted=TRUE, this is inorder to create a history of changes made to a row.
The email column in the table has a unique index which is preventing this functionality from being successful.
PostgreSQL said: duplicate key value violates unique constraint "users_email_unique"
Detail: Key (email)=(TEST) already exists.
Is there a way to apply the unique index only to rows that are marked is_deleted=FALSE, thus allowing for the changes to occur.
Since version 7.2, you can use partial indexes in PostgreSql
Add a where clause to the create index statement to make it a partial index:
CREATE UNIQUE INDEX users_email_unique ON tests (email)
WHERE NOT is_deleted; -- assuming is_deleted is Boolean
Though PostgreSql supports Alter index, from what I understand from the documentation the alter is limited to either rename or setting the tablespace.
This means that you will need to drop and re-create the index in order to change it into a partial index:
DROP INDEX users_email_unique;
CREATE UNIQUE INDEX users_email_unique ON tests (email)
WHERE NOT is_deleted; -- assuming is_deleted is Boolean
I want to introduce a column to an existing index in the below format.
Existing index:
Create index idx_indexname on tablename(id)
My new index would be
Alter index idx_indexname on tablename(id) include (column1)
I want to add columns around 300 indexes in this way. Please suggest any dynamic approaches.
Note: Most of my indexes are falling under either unique (Non Clustered) / primary key (clustered indexes)
First of all, remove all of the clusterred indexes from the list. They're already the table itself, so all columns are autimatically included.
As for all the rest, you have to drop the index and recreate it. You can use the drop_existing option, but it will essentially take the index offline.
Best to create the new indexes. Then remove the old. And rename using sp_rename to set the new indexes to the original index names.
You can drop and recreate an Index but you can not alter an index to add more columns.
Alter index is only used to set some properties of index.
I saw the following statement in a db patch:
ALTER TABLE tablename ADD PRIMARY KEY (somepk_columnname) USING INDEX;
I wanted to look up what USING INDEX does here, but only got from google, that it lets me specify some storage specific stuff, etc.
My question really is, what exactly happens here? Does the db use some default values here? Creates an index for the PK in the default tablespace? I thought that an index is created for every pk per default...
http://docs.oracle.com/cd/B28359_01/server.111/b28286/clauses002.htm#SQLRF52209
Using Indexes to Enforce Constraints
When defining the state of a unique or primary key constraint, you can
specify an index for Oracle to use to enforce the constraint, or you
can instruct Oracle to create the index used to enforce the
constraint.
using_index_clause You can specify the using_index_clause only when
enabling unique or primary key constraints. You can specify the
clauses of the using_index_clause in any order, but you can specify
each clause only once.
If you specify schema.index, then Oracle attempts to enforce the constraint using the specified index. If Oracle cannot find the index
or cannot use the index to enforce the constraint, then Oracle returns
an error.
If you specify the create_index_statement, then Oracle attempts to create the index and use it to enforce the constraint. If Oracle
cannot create the index or cannot use the index to enforce the
constraint, then Oracle returns an error.
If you neither specify an existing index nor create a new index, then Oracle creates the index. In this case:
The index receives the same name as the constraint.
If table is partitioned, then you can specify a locally or globally partitioned index for the unique or primary key constraint.
The response above was very helpful but I also wanted to use a specific tablespace for my unique key. This worked for me:
alter table tablename add constraint uk_name unique (col1, col2) using index tablespace tablespace_name;
Ok here is a non clustered index features
Now as you can see Id is the Identity column which is primary key and clustered. I can either include it into the index columns and mark index as unique or not include it to the index itself and add it as included columns.
Which one should be selected and why ? thank you
The clustered key is automatically included in the nonclustered index, whether you include it explicitly or not. In other words - don't include it, unless you need to use a predicate that filters on the clustered key and then a couple of other columns (in that order) - in that case it may make sense to force it as the first column, as it'll otherwise be stored physically as the last column.
I've made mistake creating clustered primary key on GUID column.
There are many tables that reference that table with defined foreign keys.
Table size is not significant.
I would like to convert it from clustered to non-clustered without manually dropping and recreating any foreign keys or even primary key constraint.
Is it possible to achieve that in MS SQL2005 and how if yes ?
Is it possible to achieve that ONLINE (without db down time) if yes ?
You could try creating the unique nonclustered NC index first, then drop the clustered PK. The FK should recognise this other index (but might not: never tried it).
When you run ALTER TABLE to drop the clustered PK use the ONLINE option. However, it's only available in Enterprise edition.
ALTER TABLE Mytable DROP CONSTRAINT PK_Mytable WITH (ONLINE = ON)
You can't use ONLINE for the ADD CONSTRAINT bit.
Basically, your options are limited without blocking, or creating another table first and moving data over...