如何按日期对表进行分区?
如何按日期对 SQL Server 中的行进行分区?
Bonus Chatter
在 SQL Server 中,按年份对表进行分区相对容易,例如:
- 表
Orders_2000
- 表
Orders_2001
- 表
Orders_2002
- ...
- table
Orders_2011
- table
Orders_2012
您为每年创建一个单独的表,确保包含具有与表匹配的检查约束的 Year
列:
CREATE TABLE Transactions_1999 (Year int NOT NULL DEFAULT 1999, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_1999 ADD CONSTRAINT PK_Transactions1999 PRIMARY KEY CLUSTERED (Year, TransactionID)
ALTER TABLE Transactions_1999 ADD CONSTRAINT CK_Transactions1999_Year CHECK (Year = '1999')
CREATE TABLE Transactions_2000 (Year int NOT NULL DEFAULT 2000, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2000 ADD CONSTRAINT PK_Transactions2000 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2000 ADD CONSTRAINT CK_Transactions2000_Year CHECK (Year = '2000')
CREATE TABLE Transactions_2001 (Year int NOT NULL DEFAULT 2001, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2001 ADD CONSTRAINT PK_Transactions2001 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2001 ADD CONSTRAINT CK_Transactions2001_Year CHECK (Year = '2001')
...
CREATE TABLE Transactions_2011 (year int NOT NULL DEFAULT 2011, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2011 ADD CONSTRAINT PK_Transactions2011 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2011 ADD CONSTRAINT CK_Transactions2011_Year CHECK (Year = '2011')
CREATE TABLE Transactions_2012 (Year int NOT NULL DEFAULT 2012, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2012 ADD CONSTRAINT PK_Transactions2012 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2012 ADD CONSTRAINT CK_Transactions2012_Year CHECK (Year = '2012')
然后您可以构造一个将表合并到一起的 VIEW
:
CREATE VIEW Transactions AS
SELECT * FROM Transactions_1999
UNION ALL
SELECT * FROM Transactions_2000
UNION ALL
SELECT * FROM Transactions_2001
UNION ALL
--...
SELECT * FROM Transactions_2011
UNION ALL
SELECT * FROM Transactions_2012
现在您可以查询此 Transactions
视图:
SELECT * FROM Transactions
WHERE (CustomerName LIKE 'boyd%')
OR (CustomerName LIKE '% boyd%')
数据可以插入到视图中,SQL Server 会自动将其放入它应该进入的表中:
INSERT INTO Transactions(Year, TransactionID, CustomerName)
VALUES (2012, 378922384, 'Ian Boyd')
但这不是我想要的,
我想按 age< 将数据分区到表中/em>。 TransactionDate
早于 90 天的行应放入一个表中,TransactionDate
晚于 90 天的交易应放入另一个表中:
- 表
Transactions_olderThan90Days
- table
Transactions_newerThan90Days
SQL 如此说道:
CREATE TABLE Transactions_NewerThan90Days (
TransactionDate datetime NOT NULL,
TransactionID int NOT NULL,
CustomeName varchar(50))
CREATE TABLE Transactions_OlderThan90Days (
TransactionDate datetime NOT NULL,
TransactionID int NOT NULL,
CustomeName varchar(50))
在 SQL Server 中这样的事情可能吗?
我意识到这听起来不可能,因为这意味着 SQL Server 必须不断移动数据。
How can i partition rows in SQL Server by date?
Bonus Chatter
In SQL Server it's relatively easy to partition tables by year, e.g.:
- table
Orders_2000
- table
Orders_2001
- table
Orders_2002
- ...
- table
Orders_2011
- table
Orders_2012
You create a separate table for each year, making sure to include a Year
column with a check constraint that matches the table:
CREATE TABLE Transactions_1999 (Year int NOT NULL DEFAULT 1999, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_1999 ADD CONSTRAINT PK_Transactions1999 PRIMARY KEY CLUSTERED (Year, TransactionID)
ALTER TABLE Transactions_1999 ADD CONSTRAINT CK_Transactions1999_Year CHECK (Year = '1999')
CREATE TABLE Transactions_2000 (Year int NOT NULL DEFAULT 2000, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2000 ADD CONSTRAINT PK_Transactions2000 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2000 ADD CONSTRAINT CK_Transactions2000_Year CHECK (Year = '2000')
CREATE TABLE Transactions_2001 (Year int NOT NULL DEFAULT 2001, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2001 ADD CONSTRAINT PK_Transactions2001 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2001 ADD CONSTRAINT CK_Transactions2001_Year CHECK (Year = '2001')
...
CREATE TABLE Transactions_2011 (year int NOT NULL DEFAULT 2011, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2011 ADD CONSTRAINT PK_Transactions2011 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2011 ADD CONSTRAINT CK_Transactions2011_Year CHECK (Year = '2011')
CREATE TABLE Transactions_2012 (Year int NOT NULL DEFAULT 2012, TransactionID int NOT NULL, CustomerName varchar(50))
ALTER TABLE Transactions_2012 ADD CONSTRAINT PK_Transactions2012 PRIMARY KEY (Year, TransactionID)
ALTER TABLE Transactions_2012 ADD CONSTRAINT CK_Transactions2012_Year CHECK (Year = '2012')
Then you can construct a VIEW
that merges to tables together:
CREATE VIEW Transactions AS
SELECT * FROM Transactions_1999
UNION ALL
SELECT * FROM Transactions_2000
UNION ALL
SELECT * FROM Transactions_2001
UNION ALL
--...
SELECT * FROM Transactions_2011
UNION ALL
SELECT * FROM Transactions_2012
And now you can query this Transactions
view:
SELECT * FROM Transactions
WHERE (CustomerName LIKE 'boyd%')
OR (CustomerName LIKE '% boyd%')
And data can be inserted into the view, and SQL Server will automatically put it in the table it's supposed to go in:
INSERT INTO Transactions(Year, TransactionID, CustomerName)
VALUES (2012, 378922384, 'Ian Boyd')
But that's not what i want
i want to partitions data into tables by age. Rows with a TransactionDate
older than 90 days should go into one table, and transactions with a TransactionDate
newer than 90 days go into another table:
- table
Transactions_olderThan90Days
- table
Transactions_newerThan90Days
So says the SQL:
CREATE TABLE Transactions_NewerThan90Days (
TransactionDate datetime NOT NULL,
TransactionID int NOT NULL,
CustomeName varchar(50))
CREATE TABLE Transactions_OlderThan90Days (
TransactionDate datetime NOT NULL,
TransactionID int NOT NULL,
CustomeName varchar(50))
Is such a thing possible in SQL Server?
i realize this sounds impossible, since it means SQL Server having to move data constantly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从 SQL 2008 开始,您可以按周或按月创建表分区,具体取决于您希望切换数据的频率。还要看看并行处理,如果您的大多数问题都调用三个或四个分区,那么相同数量的处理器开始并行工作以获得您的答案。
(我不建议按天使用分区,因为 3 年内就会达到 1000 个分区的限制)。
As of SQL 2008 you can create table partitions by week or by month depending on how often you would like to switch data. Have a look at parallel processing too, if most of your questions invoke three or four partitions then the same number processors start working in parallel for your answers.
(I would not advise to use partitions by day, because the limit of 1000 partitions is then reached within 3 years).