I'd like to add a constraint which enforces uniqueness on a column only in a portion of a table.
ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null);
The WHERE part above is wishful thinking.
Any way of doing this? Or should I go back to the relational drawing board?
PostgreSQL doesn't define a partial (i.e. conditional) UNIQUE constraint - however, you can create a partial unique index.
PostgreSQL uses unique indexes to implement unique constraints, so the effect is the same, with an important caveat: you can't perform upserts (ON CONFLICT DO UPDATE) against a unique index like you would against a unique constraint.
Also, you won't see the constraint listed in information_schema.
CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is NOT null);
See partial indexes.
it has already been said that PG doesn't define a partial (ie conditional) UNIQUE constraint. Also documentation says that the preferred way to add a unique constraint to a table is ADD CONSTRAINT Unique Indexes
The preferred way to add a unique constraint to a table is ALTER TABLE ... ADD CONSTRAINT. The use of indexes to enforce unique constraints could be considered an implementation detail that should not be accessed directly. One should, however, be aware that there's no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.
There is a way to implement it using Exclusion Constraints, (thank #dukelion for this solution)
In your case it will look like
ALTER TABLE stop ADD CONSTRAINT myc EXCLUDE (col_a WITH =) WHERE (col_b IS null);
Related
I find this abit confusing. Iam using memsql column store. I try to understand if there is a way to enforce duplications on specific key (e.g eventId). I found some doc regarding Unenforced Unique but I didnt really understand its intention.
The point of unenforced unique keys is as a hint:
An unenforced unique constraint is informational: the query planner may use the unenforced unique constraint as a hint to choose better query plans.
from https://docs.memsql.com/v6.8/concepts/unenforced-unique-constraints/.
Unfortunately MemSQL does not support (enforced) unique constraints on columnstore tables.
MemSQL now supports unique constraint with version 7+ but can be applied to only single column:
https://docs.memsql.com/v7.1/guides/use-memsql/physical-schema-design/creating-a-columnstore-table/creating-a-columnstore-table/
Your columnstore table definition can contain metadata-only unenforced unique keys, single-column hash keys (which may be UNIQUE), and a FULLTEXT key. You cannot define more than one unique key.
one hack to enable UNIQUE constraint on multi columns is to use a computed column consisting of multiple columns appended and then apply UNIQUE on it which will indirectly enforce uniqueness on multiple columns.
example:
CREATE TABLE articles (
id INT UNSIGNED,
year int UNSIGNED,
title VARCHAR(200),
body TEXT,
SHARD KEY(title),
KEY (id) USING CLUSTERED COLUMNSTORE,
KEY (id) USING HASH,
UNIQUE KEY (title) USING HASH,
KEY (year) USING HASH);
With Firebird, if I have a check constrained by a subquery to another table, and I write to the table in the subquery that would violate the check, what fails, if anything?
If nothing fails, will the constraint be violated on the next read from the table with the check constraint? If not, what does Firebird do to prevent the constraint from being violated on read?
Example
table_a has a check constraint on column_a_table_a that should be < SUM(column_a_table_b) FROM table_b.
A CHECK CONSTRAINT only applies to the table it is defined on, and only guarantees integrity if the constraint is derived from the row it is applied to.
This is also documented in the Interbase 6.0 Data Definition Guide on page 106 (available from the reference manual section of the Firebird site):
Note A CHECK constraint guarantees data integrity only when the values being verified are in the same row that is being inserted and deleted. If you try to compare values in different rows of the same table or in different tables, another user could later modify those values, thus invalidating the original CHECK constraint that was applied at insertion time.
So if you modify table_b in such a way that the check contraint applied to table_a no longer holds, then you will not receive an error because this constraint does not apply to this table.
Now if you modify table_a, the check constraint will fire and will result in an error (only for modified row(s), and only where the constraint no longer holds).
I'm trying to figure out the best schema for working with both counters and non-counting values. All these values are supposed to be in the same spot and I was going to work with wide columns but because Cassandra doesn't support a mixture of those types, that won't work.
Would I have to create a separate column family, one to hold the counters, and the other to hold other data types?
Yes you are absolutely correct in your understanding.
Always maintain separate column family for maintaining the counter. Also since in counter column familiy's new feature to have some normal column as a part of compound key gives us an added advantage.
Counter data type can't be used as a primary key.
All non-row key fields have to have counter data type.
I'm trying to set up my postgres schema in yesod. The plan is to let yesod generate the tables, but I'll be inserting new records into the tables from a lua script in a C++ program. I'd like one of the tables to have a primary key based on a unique Int64 that comes from the C++ environment. Can I get Persistent to treat this column as the table key, but without the automatic id generation?
I guess I could have a regular persistent-style record ID column and an Int64 column too but that seems wasteful and overly complicated. The Int64 will always be unique and that's what I'll use to do lookups on the table records to see if they exist already.
I think this question was asked on the mail list. The short answer is no, the primary key in Persistent is auto-increment, but you can have secondary indexes
Disclaimer: I jumped to C# 2008 recently and SubSonic 3 (3.0.0.4) at the same time. I haven't used Linq for much of anything in the past.
Is there an easy way to use the foreign key display value for sorting, rather than the FK Id (which is numeric)?
I've added a new Find method in my ActiveRecord.tt to help with sorting based on a string field name but after doing some testing I realized that even though its working as it should be, I am not handling foreign key fields at all (they are just sorting by their value).
Even if I need to change how I am accessing the data it is early enough in the project to do that. Just looking for suggestions.
LINQ is your friend in this situation, you just need to join your two objects and then sort by the property from your foreign object:
var primaryObjectsSorted =
from primaryObjects in PrimaryObject.All()
join foreignObjects in ForeignObject.All()
on primaryObjects.ForeignId equals foreignObjects.Id
orderby foreignObjects.PropertyYouWantToSortOn
select primaryObjects;
So you have table A which has id of table B as a foreign key and you want to sort table A by the DisplayName column of table B rather than the id of table B?
The only way to achive this is by a join.
SELECT tableA.* FROM tableA INNLER JOIN tableB ORDER BY tableB.DisplayName
In SubSonic2 you can do that, and still be able to update your records if you use the DB.Select(...).ExecuteCollection() method.
I think this should be possible with subsonic3, too.
Howevery, if you don't use the foreign key and the display name is unique, you should just use this value as your foreign key.