I have a huge table for logging. The definition is:
CREATE TABLE [dbo].[TRACELOG]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TYPE] [varchar](15) NOT NULL,
[DATEHEURE] [datetime] NOT NULL,
[PROGRAMME] [varchar](25) NOT NULL,
[APPLICATION] [varchar](50) NOT NULL,
[DESCRIPTION] [text] NULL,
[UTILISATEUR] [varchar](10) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Indexes are like this:
The table has now about 18 millions or row. When I run a query using ID = 123456, the query is very long.
SELECT *
FROM TRACELOG
WHERE ID = 123456
I'm very surprised... My question is: in a table with IDENTITY, is there an implicit index created on the column in question (not visible in indexes?) or have I to create manually?
NO - having an IDENTITY column does not automatically create an index.
What does create an automatic (and by default clustered) index is the PRIMARY KEY constraint - which is often used on IDENTITY columns.
But not every IDENTITY column has to be the primary key of its table - you have to specify that if you want it that way.
Related
I am writing application to store and retrieve stock market price data which the data is inserted on daily basis. I am storing the data for each asset (Stock) and for most of the market in the world. This is my current design of the tables
Country table:
CREATE TABLE [dbo].[List_Country]
(
[CountryId] [char](2) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[CurrenyCode] [nvarchar](5) NULL,
[CurrencyName] [nvarchar](50) NULL
CONSTRAINT [PK_dbo.List_Country]
PRIMARY KEY CLUSTERED ([CountryId] ASC)
)
Asset table:
CREATE TABLE [dbo].[List_Asset]
(
[AssetId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NOT NULL,
[CountryId] [char](2) NOT NULL,
CONSTRAINT [PK_dbo.List_Asset]
PRIMARY KEY CLUSTERED ([AssetId] ASC)
)
Foreign key constraint on Country:
ALTER TABLE [dbo].[List_Asset] WITH CHECK
ADD CONSTRAINT [FK_dbo.List_Asset_dbo.List_Country_CountryId]
FOREIGN KEY([CountryId])
REFERENCES [dbo].[List_Country] ([CountryId])
ON DELETE CASCADE
GO
Stock_Price table:
CREATE TABLE [dbo].[Stock_Price_Data]
(
[StockPriceDataId] [int] IDENTITY(1,1) NOT NULL,
[AssetId] [int] NOT NULL,
[PriceDate] [datetime] NOT NULL,
[Open] [int] NOT NULL,
[High] [int] NOT NULL,
[Low] [int] NOT NULL,
[Close] [int] NOT NULL,
[Volume] [int] NOT NULL,
CONSTRAINT [PK_dbo.Stock_Price_Data]
PRIMARY KEY CLUSTERED ([StockPriceDataId] ASC)
)
Foreign key constraint on Asset:
ALTER TABLE [dbo].[Stock_Price_Data] WITH CHECK
ADD CONSTRAINT [FK_dbo.Stock_Price_Data_dbo.List_Asset_AssetId]
FOREIGN KEY([AssetId])
REFERENCES [dbo].[List_Asset] ([AssetId])
ON DELETE CASCADE
The concern I have at the moment is Stock_Price_Data table would be filled with high volume rows, i.e. For a specific market in a country, there can be easily 20,000 assets. Thus, in a year (260 days of trading) , I could potentially have 5.2 million rows for each country.
The application does not restrict a user from accessing data other than default country (which is setup during login).
Is it a good idea to have separate table (i.e. Stock_Price_Data_AU) for each country? Or is there a better way to design the database for the above scenario?
-Alan-
First of all - I'd drop the _data from the table name - its overkill.
If you are reasonably certain that the users will always filter the data by Country - ie only looking at 1 country at a time then I'd consider partitioning the table by Country ID - this way SQL Server will use partition elimination to pick only the relevant data. This way you get the ease of maintenance from 1 table but you get the performance as if it is a separate table per country. (I'm assuming you have Enterprise Edition) If your load works on a per country basis too then you can even switch out the partition and then drop the indexes to get even faster loads.
the table:
CREATE TABLE [dbo].[User] (
[UserName] NVARCHAR (100) NOT NULL,
[Pasword] NVARCHAR (100) NOT NULL,
[Name] TEXT NOT NULL,
[LastName] TEXT NOT NULL,
[Location] TEXT NOT NULL,
[profesion] TEXT NOT NULL,
[Email] NVARCHAR (50) NOT NULL,
[Gender] TEXT NOT NULL,
PRIMARY KEY CLUSTERED ([UserName] ASC)
);
i want to update to:
CREATE TABLE [dbo].[User] (
[UserName] NVARCHAR (100) NOT NULL,
[Pasword] NVARCHAR (100) NOT NULL,
[Name] TEXT NOT NULL,
[LastName] TEXT NOT NULL,
[Location] TEXT NOT NULL,
[profesion] TEXT NOT NULL,
[Email] NVARCHAR (50) NOT NULL,
[Gender] TEXT NOT NULL,
[moneyinmillions] INT NOT NULL,
PRIMARY KEY CLUSTERED ([UserName] ASC)
);
the problem:
an error occurred while the batch was being executed
thanks for the help
In the interest of answering your question, here is the code you would want to add the moneyinmillions column to the User table:
ALTER TABLE [User]
ADD [moneyinmillions] INT NOT NULL;
Ways to Insert a column in your existing Table
Use the ALTER TABLE Statement
Do the following:
ALTER TABLE [dbo].[User]
ADD [moneyinmillions] INT NOT NULL
Using the Table Designer
In Object Explorer, right-click the table (here, User table) to which you want to add columns and choose Design.
Click in the first blank cell in the moneyinmillions column.
Press the TAB key to go to the Data Type cell and select a Data Type from the dropdown.
When you are finished adding columns, from the File menu, choose Save table name (User).
Using DROP TABLE and Re-Creating the Table
DROP TABLE [dbo].[User]
and then Execute the statements below:
CREATE TABLE [dbo].[User] (
[UserName] NVARCHAR (100) NOT NULL,
[Pasword] NVARCHAR (100) NOT NULL,
[Name] TEXT NOT NULL,
[LastName] TEXT NOT NULL,
[Location] TEXT NOT NULL,
[profesion] TEXT NOT NULL,
[Email] NVARCHAR (50) NOT NULL,
[Gender] TEXT NOT NULL,
[moneyinmillions] INT NOT NULL,
PRIMARY KEY CLUSTERED ([UserName] ASC));
(Note: The DROP Table Statement will remove the table definition and all the data, indexes, triggers, constraints, and permission specifications for that table. So, if you have data entry in some fields/columns, then do not use the DROP TABLE Statement because you'll loose all the data).
Did you know that you can right click on the table and open the design view to add/remove columns to or from a table ??
When I execute this query, I am getting an error
Cannot find data type dbo.GUID_PK
For this should I create table for CandidateRoleID or what else should I do here?
But, when I googled it I found it saying SQL Server stores GUID. How could I access it or what is the correct way of declaring this table? I searched in google about GUID_PK.
But didn't find any syntax or explanation. Thanks in advance.
CREATE TABLE [dbo].[tbl]
(
[CandidateRoleID] [dbo].[GUID_PK] NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL
);
The SQL server data type for a GUID is UNIQUEIDENTIFIER.
Your script should be:
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
CONSTRAINT PK_Tbl PRIMARY KEY (CandidateRoleID));
If you want it to be 'automatically' created, similar to an integer identity column, give it a default:
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
CONSTRAINT PK_Tbl PRIMARY KEY (CandidateRoleID));
CREATE TABLE [dbo].[tbl](
[CandidateRoleID] [uniqueidentifier] primary key NOT NULL,
[CandidateID] [uniqueidentifier] NOT NULL,
[RoleID] [int] NOT NULL,
);
In SQL server GUID is uniqueidentifier data type.
There is no data type 'GUID_PK' in sql server.
GUID is an acronym for Global Unique ID(entifier) and is a unique 16
byte number. The term GUID and UNIQUEIDENTIFIER are often
interchangeable within the SQL Server community.
If you need to auto-generate uniqueidentifier value in your table during data insert, the consider adding default value to the uniqueidentifier data-type.
CREATE TABLE #tbl(
[CandidateRoleID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[CandidateID] [uniqueidentifier] NOT NULL DEFAULT NEWID(),
[RoleID] [int] NOT NULL);
GO
INSERT INTO #tbl (ROLEID) SELECT (1)
CandidateRoleID CandidateID RoleID
F20AE15E-8D97-4042-8AA8-DD7BCB0EB6D6 FAE29358-BD34-4BFE-800B-E332375E020E 1
I am using SQL Server 2005, and I have 3 tables:
CREATE TABLE [dbo].[Workflow]
(
[WorkflowId] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Description] [varchar](1000) NULL
)
CREATE TABLE [dbo].[Application]
(
[ApplicationId] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[Rel_Workflow_Application]
(
[WorkflowId] [int] NOT NULL,
[ApplicationId] [int] NOT NULL
)
The rule is that in Rel_Workflow_Application, ApplicationId must exist in the Application table or it can be 0. I don't have a record in table Application where ApplicationId = 0 and I don't wish to create one.
How can I set this constraint?
Though it is possible to use the NOCHECK when creating a foreign key, this is a hack that might prove problematic. I would use null instead of 0 and if 0 needs to show up in queries use coalesce(ApplicationID, 0) in the select statements or create a view which does this and query that view instead.
This cleanly indicates that the foreign key does not have a row in Application.
I'm developing a SQL SERVER 2012 express and developer solution.
I will receive an xml in an stored procedure. In the stored procedure I will parse the xml and insert its data into a table.
My problem here is that in this xml could contain data that exists on the table, and I need to update the data on the table with the new one.
I don't want to check if each row in xml exists on the table.
I think I can use IGNORE_DUP_KEY but I'm not sure.
How can I update or insert new data without checking it?
This is the table where I want to insert (or update) the new data:
CREATE TABLE [dbo].[CODES]
(
[ID_CODE] [bigint] IDENTITY(1,1) NOT NULL,
[CODE_LEVEL] [tinyint] NOT NULL,
[CODE] [nvarchar](20) NOT NULL,
[COMMISIONING_FLAG] [tinyint] NOT NULL,
[IS_TRANSMITTED] [bit] NOT NULL,
[TIMESPAN] [datetime] NULL,
[USERNAME] [nvarchar](50) NULL,
[SOURCE] [nvarchar](50) NULL,
[REASON] [nvarchar](200) NULL
CONSTRAINT [PK_CODES] PRIMARY KEY CLUSTERED
(
[CODE_LEVEL] ASC,
[CODE] ASC
)
)
The "IGNORE_DUP_KEY" parameter ,is ignore inserting new row, if he is already exists, but it is not dealing with update in case it exists.
the solution to your request is by MERGE or DML operation (INSERT/UPDATE/DELETE) .
BTW,
The parameter "IGNORE_DUP_KEY" is covering existsnce for the index key only (index column).