https://commitfest.postgresql.org/16/1452/
If everything goes well, it might be in PostgreSQL 11.
Where TransactionId should be globally unique?
[ed: see https://news.ycombinator.com/item?id=16196096 for a much better/comprehensive example of the same idea]
Say new_key = <part_unique-id>-<part_key>. Now new_key is guaranteed unique across the partition space. You could consider hashing as well...although I don't recommend this since hashes don't have collision guarantees (even if the chances of collisons are small for most modern algorithms).
Say my table is a Student table: StudentId, Building, Name, Birthdate, Gender, Grade, Status. I want to partition by Status so that Active students are together, but StudentId must be unique across the entire district.
CREATE SEQUENCE student_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
And anywhere you create a student you would set default to be next value in the sequence: ALTER COLUMN id SET DEFAULT nextval('student_id_seq'::regclass);
Although, in this example I am pretty sure a valid limitation of the model could be that students must be created with "Active" status...which then confuses me slightly since you wouldn't really partition by status since updating the status of a student is an action so I would move the user record at that time. Which is no longer partitioning per se.But this is one (probably naiive) way to handle this case.
Yes, if the applications using the database have no bugs and always work as expected, then you won't have any duplicates. However, that line of reasoning leads to just 100% trusting everything the application does regardless of the design of the data model. That's exactly how data stores used to work before RDBMSs, and it's exactly why RDBMSs came about: applications can't be trusted to manipulate data consistently to a known set of rules. Somebody will mess it up somewhere, so it's important to enforce rules to leave the database in a manner that other applications (or other parts of the same application) will find comprehensible.
This is true. And while you could claim it is a "non-starter" for using partitions I would argue that app logic guarantees of how that column is used is sufficient for many cases to actually use in its current state.
You have good points, and I have no disagreement about data integrity constraints or whether or not partition-wide uniqueness guarantees are a good feature.
It would seem you and I simply disagree on whether or not partitions without uniqueness guarantees are unusable for most use cases. I believe many partitions use cases don't need uniqueness guarantees (such as high volume, low/no update work loads). And for quite a few, if definitely not all, cases where uniqueness is desirable it could be satisfactorily handled in app logic.
But again, key agreement is partition-wide uniqueness guarantees are a good feature.
Let's say you want a table for your account transactions:
create table transaction (
tran_id int primary key not null,
tran_date timestamp(0) not null,
account int not null,
amount decimal(30,4) not null
);
Now if there's already a transaction with an id of 8043, you can't insert another transaction with that same id. There's only one transaction with 8043 allowed in the whole table. However, if we partition the table: create table transaction (
tran_id int not null,
tran_date timestamp(0) not null,
account int not null,
amount decimal(30,4) not null
) partition by range (tran_date);
create table transaction_y2018m01 partition of transaction
for values from ('2018-01-01 00:00:00') to ('2018-01-31 23:59:59');
create table transaction_y2018m02 partition of transaction
for values from ('2018-02-01 00:00:00') to ('2018-02-28 23:59:59');
alter table transaction_y2018m01 add constraint ux_transaction_y2018m01_tran_id unique (tran_id);
alter table transaction_y2018m02 add constraint ux_transaction_y2018m02_tran_id unique (tran_id);
See, the only uniqueness restrictions are on the partitions, not the overall table. Now I could potentially have a transaction with an id of 8043 in both January and February of 2018, as well as any number of transactions with an id of 8043 not in either of those two months. If my application assumes that transaction ids are always unique, that's got the potential to cause a problem. If multiple applications or multiple users use the same database, it's possible that an error or a race condition might cause a duplicate id.[0] https://blog.twitter.com/engineering/en_us/a/2010/announcing...