I need to alter the length of a column column_length in say more than 500 tables and the tables might have no of records ranging from 10 records to 3 or 4 million records.
The column may just be a normal column
CREATE TABLE test(column_length varchar(10))
The column might contain non-clustered index on it.
CREATE TABLE test(column_length varchar(10))
CREATE UNIQUE NONCLUSTERED INDEX column_length_ind ON test (column_length)
The column might contain PRIMARY KEY clustered index on it
CREATE TABLE test(column_length varchar(10))
ALTER TABLE test ADD PRIMARY KEY CLUSTERED INDEX ON column_length
The column might be a composite primary key
The column might have a foreign key reference
In short the column column_length might be anything.
All I need is to create scripts to alter the length of the column_length from varchar(10) to varchar(50). Should I drop the indexes before altering and then recreate them? What about the primary key and foreign key?
Through my research and testing I figured out that I can just alter the column's length without dropping the primary key or any indexes but have to drop and recreate the foreign key alone.
Is this assumption right?
Yes you should be able to just modify the columns. From my experience it is faster to leave the index and primary key in place.
Likely you will need to do alter column on the foreign key tables as well to increase the size. SO first you drop the fk constraint, then fix the forign kkey fields, then fix the primary key field then put the constraints back on.
Related
I have table with about 60 000 000 rows in it and having size near 60 GB.
It has 2 indexes: clustered index and primary key on same id identity column.
Primary key index has size near 1GB. It looks excessive. I have several such tables.
Question is, is there any way to effectively mark existing clustered index as primary key also without dropping both indexes and creating one single new index?
Sub question is does it worth it to do such operations, maybe only drop primary keys? What's the real practical advantage of having primary key except descriptive usage for 3rd party tools? maybe sql server optimizer uses this metadata to optimize queries or any other advantages that I am missing?
Small sample of what I want to achieve, but other way (if it exists), without dropping and creating indexes.
I assume that it looks like there's no other way really, but who knows maybe there's some trick.
create table a
(
id int identity,
col1 varchar(50)
)
create unique clustered index cix_id on a(id)
alter table a add constraint pk_a primary key nonclustered(id)
select t.name,i.name,i.is_primary_key,i.type_desc from
sys.tables t
inner join sys.indexes i on i.object_id=t.object_id
where t.name='a'
drop index cix_id on a
alter table a drop constraint pk_a
alter table a add constraint pk_a primary key clustered(id)
select t.name,i.name,i.is_primary_key,i.type_desc from
sys.tables t
inner join sys.indexes i on i.object_id=t.object_id
where t.name='a'
I am using SQL Server 2012 & am creating a table that will have 8 columns, types below
datetime
varchar(12)
varchar(6)
varchar(100)
float
float
int
datetime
Once a day (normally) there will be an upload of approx 10,000 rows of data. Going forward its possible it could be 100,000.
The rows will be unique if I group on the first three columns listed above. I have read I can use the unique constraint on multiple columns which will guarantee the rows are unique.
I think I'm correct in saying that the unique constraint by default sets up non-clustered index. Would a clustered index be better & assuming when the table starts to contain millions of rows this won't cause any issues?
My last question. By applying the unique constraint on my table I am right to say querying the data will be quicker than if the unique constraint wasn't applied (because of the non-clustering or clustering) & uploading the data will be slower (which is fine) with the constraint on the table?
Unique index can be non-clustered.
Primary key is unique and can be clustered
Clustered index is not unique by default
Unique clustered index is unique :)
Mor information you can get from this guide.
So, we should separate uniqueness and index keys.
If you need to kepp data unique by some column - create uniqe contraint (unique index). You'll protect your data.
Also, you can create primary key (PK) on your columns - they will be unique also. But, there is a difference: all other indexies will use PK for referencing, so PK must be as short as possible. So, my advice - create Identity column (int or bigint) and create PK on it. And, create unique index on your unique columns.
Querying data may become faster, if you do queries on your unique columns, if you do query on other columns - you need to create other, specific indexies.
So, unique keys - for data consistency, indexies - for queries.
I think I'm correct in saying that the unique constraint by default
sets up non-clustered index
TRUE
Would a clustered index be better & assuming when the table starts to
contain millions of rows this won't cause any issues?
(1)if u need to make (datetime ,varchar(12), varchar(6)) Unique
(2)if you application or you will access rows using datetime or datetime ,varchar(12) or datetime ,varchar(12), varchar(6) in where condition
ALL the time
then have primary key on (datetime ,varchar(12), varchar(6))
by default it will put Uniqness and clustered index on all above three column.
but as you commented above:
the queries will vary to be honest. I imagine most queries will make
use of the first datetime column
and you will deal with huge data and might join this table with other tables
then its better have a surrogate key( ever-increasing unique identifier ) in the table and to satisfy your Selects
have Non-Clustered INDEXES
Surrogate Key vs Business Key
NON-CLUSTERED INDEX
I have not done much database design work and I was searching around for some example.
While I know the difference from a primary and foreign key, one thing that caught be off guard was that even if a Table has a primary key and is used as a foreign key in another table, as I was used the GUI SSMS tools, I noticed that I sometime end up having this
PhoneID (PK, int, not null)
While my User table
UserId(PK,FK, int, not null)
BOTH of these tables have these ID's as primary keys in those tables, along with foreign keys in other tables, but why does one of them have "PK,FK" obviously I accidentally created it, but should it be like that?
It is Possible for a Primary key to be a Foreign Key as well at the same time.
But looking at you database design, In your case I dont think it was intentional it was done by mistake. And if it wasnt done by mistake then you need to fix it.
In your dbo.PhoneType Table the column PhoneTypeID needs to be a Primary key only not a Foreign key. My guess is this was done by mistake, you wanted to create a Foreign key in your dbo.Phone table on column PhoneTypeID referencing PhoneTypeID column in dbo.PhoneType table. But somehow you end up create a foreign key constraint on the Primary key column of the dbo.Phontype table.
This Design contradicts constraints.
In simple english : The foreign Key Constraint on your dbo.PhoneType(PhoneTypeID) enforces that you cannot have a PhoneTypeID in dbo.PhoneType table unless it exists in PhoneTypeID column of dbo.Phone table.
On the other hand Foreign Key Constraint on dbo.Phone(PhoneTypeID) enforces that you cannot have a PhoneTypeID in dbo.Phone unless it exists in dbo.PhoneType(PhoneTypeID).
and same is true for the UserID column in dbo.Users table.
Solution
You need to drop the following Constraints to make it work properly.
1) In dbo.PhoneType table Drop Foreign key constraint referencing
PhoneTypeID column in dbo.phone table.
2) In dbo.Users Table drop the Drop Foreign key constraint referencing
UserID column in dbo.phone table.
It's entirely possible, yes. A primary key of a table could also be a foreign key referencing another table.
In your case, I'm not exactly sure what you did. You can check the constraints to see which column the UserId column is referencing.
As an additional note, simply adding a foreign reference to a table does not implicitly make that column a foreign key on another table. For example, just because you add FK_PhoneTypeID to the Phone table, SQL Server does not automatically make PhoneTypeID column in the PhoneType table a FK. In your statements, somewhere, it's possible that you made assignments to other columns, or even to themselves.
I have a table that I intended to partition by a nullable column.
This seems to work just fine except for the primary key. I get an error:
Partition columns for a unique index must be a subset of the index key
Create a primary key on a different filegroup. This doesn't work because it removes partitioning.
Skip the primary key all together and create a clustered index (non-unique). This won't work exactly because I need a primary key.
Any idea on how I can get a primary key on a partitioned table where the partition column is nullable? If not, I am open to suggestions on how to handle it another way.
Thanks in advance.
Not sure what really blocked you. You can create PK on your unique column, and have your partition column with nullable. Just not to only create unique cluster index on only PK column. When you need to create unique cluster index, add you PK column and the partition column together.
I am listing all FK constraints for a given table using INFORMATION_SCHEMA set of views with the following query:
SELECT X.UNIQUE_CONSTRAINT_NAME,
"C".*, "X".*
FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" AS "C"
INNER JOIN "INFORMATION_SCHEMA"."REFERENTIAL_CONSTRAINTS" AS "X"
ON "C"."CONSTRAINT_NAME" = "X"."CONSTRAINT_NAME"
AND "C"."TABLE_NAME" = 'MY_TABLE'
AND "C"."TABLE_SCHEMA" = 'MY_SCHEMA'
Everything works perfectly well, but for one particular constraint the value of UNIQUE_CONSTRAINT_NAME column is wrong, and I need it in order to find additional information from the referenced Column. Basically, for most of the rows the UNIQUE_CONSTRAINT_NAME contains the name of the unique constraint (or PK) in the referenced table, but for one particular FK it is the name of some other unique constraint.
I dropped and re-created the FK - did not help.
My assumption is that the meta-data is somehow screwed. Is there a way to rebuild the meta data so that the INFORMATION_SCHEMA views would actually show the correct data?
edit-1: sample db structure
CREATE TABLE MY_PARENT_TABLE (
ID INTEGER,
NAME VARCHAR,
--//...
CONSTRAINT MY_PARENT_TABLE_PK PRIMARY KEY CLUSTERED (ID)
)
CREATE UNIQUE NONCLUSTERED INDEX MY_PARENT_TABLE_u_nci_ID_LongName ON MY_PARENT_TABLE (ID ASC) INCLUDE (SOME_OTHER_COLUMN)
CREATE TABLE MY_CHILD_TABLE (
ID INTEGER,
PID INTEGER,
NAME VARCHAR,
CONSTRAINT MY_CHILD_TABLE_PK PRIMARY KEY CLUSTERED (ID)
,CONSTRAINT MY_CHILD_TABLE__MY_PARENT_TABLE__FK
FOREIGN KEY (PID)
REFERENCES MY_PARENT_TABLE (ID)
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
I expect the UNIQUE_CONSTRAINT_NAME to be MY_PARENT_TABLE_PK, but what I am
getting is MY_PARENT_TABLE_u_nci_ID_LongName.
Having looked at the structure, I see that in fact there are 2 UNIQUE constaints on that column - PK and the MY_PARENT_TABLE_u_nci_ID_LongName. So the real question should probably be: why does it take some other unique index and not the PK?
Since you have both a PK and a UNIQUE constraint on the same column, SQL Server picks one to use. I don't know if it picks the UNIQUE constraint because it is thinner (i.e. fewer columns involved) and might require fewer reads to confirm matches(?)
I don't see any way within SQL to enforce which one it chooses, other than ordering your scripts - create the table with the PK, create the other table and the FK, then create the UNIQUE constraint if you really need it - but is that really the case?