Primary key defined by many attributes? - postgresql

Can I define a primary key according to three attributes? I am using Visual Paradigm and Postgres.
CREATE TABLE answers (
time SERIAL NOT NULL,
"{Users}{userID}user_id" int4 NOT NULL,
"{Users}{userID}question_id" int4 NOT NULL,
reply varchar(255),
PRIMARY KEY (time, "{Users}{userID}user_id", "{Users}{userID}question_id"));
A picture may clarify the question.

Yes you can, just as you showed.(though I question your naming of the 2. and 3. column.)
From the docs:
"Primary keys can also constrain more than one column; the syntax is similar to unique constraints:
CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);
A primary key indicates that a column or group of columns can be used as a unique identifier for rows in the table. (This is a direct consequence of the definition of a primary key. Note that a unique constraint does not, by itself, provide a unique identifier because it does not exclude null values.) This is useful both for documentation purposes and for client applications. For example, a GUI application that allows modifying row values probably needs to know the primary key of a table to be able to identify rows uniquely.
A table can have at most one primary key (while it can have many unique and not-null constraints). Relational database theory dictates that every table must have a primary key. This rule is not enforced by PostgreSQL, but it is usually best to follow it.
"

Yes, you can. There is just such an example in the documentation.. However, I'm not familiar with the bracketed terms you're using. Are you doing some variable evaluation before creating the database schema?

yes you can
if you'd run it - you would see it in no time.
i would really, really, really suggest to rethink naming convention. time column that contains serial integer? column names like "{Users}{userID}user_id"? oh my.

Related

Is there efficient difference between varchar and int as PK

Could somebody tell is it good idea use varchar as PK. I mean is it less efficient or equal to int/uuid?
In example: car VIN I want to use it as PK but I'm not sure as good it will be indexed or work as FK or maybe there is some pitfalls.
It depends on which kind of data you are going to store.
In some cases (I would say in most cases) it is better to use integer-based primary keys:
for instance, bigint needs only 8 bytes, varchar can require more space. For this reason, a varchar comparison is often more costly than a bigint comparison.
while joining tables it would be more efficient to join them using integer-based values rather that strings
an integer-based key as a unique key is more appropriate for table relations. For instance, if you are going to store this primary key in another tables as a separate column. Again, varchar will require more space in other table too (see p.1).
This post on stackexchange compares non-integer types of primary keys on a particular example.

Do I need to use a auto-generated column as primary key, when I have a UUID from authorization server?

I am writing a resource server based on OAuth2 structure. I have a table user, and I will be storing the sub claim of JWT response into that table as a unique key for other table to reference it. I tried to do this in order to avoid checking the database for each incoming request.
If that key(sso_id) is already unique, do I still need to have a id key that will be generated automatically? Is there any performance gain/loss for omitting that key?
DROP TABLE IF EXISTS "user";
CREATE TABLE "user" (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
sso_id VARCHAR(100) NOT NULL UNIQUE
);
No, you do not need to generate a different Primary Key. A primary must meet 2 requirements, nothing else. It must not be null or partially null, and it must be unique within the table. As long as it meets those requirements, it is valid. Some would argue that you should generate a PK (has some validity), but that is a philosophical argument a specified requirement. You could actually use the value passed as the PK, and perhaps even a FK. I am torn between assuming that you single sign-on (sso_id) and the passed jwt_id are the same or not. Why would you define it as 100 characters, which is much larger than required if they were, but it also seems logical that they would be. I will assume they are not. Also I assume that reference to originating table is available. With that then the following would be perfectly valid.
create table "user" (
jwt_id uuid
, sso_id varchar(100) not null unique
, constraint user_pk
primary_key(jwt_id)
, constraint user_2_jwt_fk
foreign key (jwt_id)
references jwt(jwt_id)
);

Are Postgres constrains per table or db?

Can I have two tables with different constrains that are names the same - that is:
Table A with constraint C
Table B with constraint C
The constrains are different
Thanks!
I couldn't find any suitable reference in the documentation but it would seem that the uniqueness of the constraint name depends on the type of constraint.
unique and primary key constraint names must be unique and may not be reused in multiple tables, but check and foreign key constraint names can be used in multiple tables (although that might be a bad idea for obvious reasons).
I would guess that the reason is that unique and primary key constraints create indexes and therefore needs to be uniquely named.
I didn't find where is it mentionned in postgres documentation. Here's a confirmation that constraint name but be different in the database.
CREATE TABLE type_position(
type_position INTEGER CONSTRAINT pk_type_position PRIMARY KEY,
description VARCHAR( 64 )
);
CREATE TABLE type_position2(
type_position INTEGER CONSTRAINT pk_type_position PRIMARY KEY,
description VARCHAR( 64 )
);
And I got the message
ERROR: relation "pk_type_position" already exists

computed hashybtes column used as primary key

I have long gene sequence which could be the natural primary key, but I'm looking for a way to find a more succinct alternative representation of the natural key. Do not want to use a surrogate key. Not worried about performance, since there will not be a lot of joins to worry about where the efficiency of the PK is an issue.
Is this possible?
create table foo(
myvalue varchar(2000) not null,
md5 as hashbytes('MD5',myvalue) PERSISTED PRIMARY KEY NOT NULL -- bad syntax
)
If so, what's the correct syntax? The above is not correct.
Also can I create a child table and set up an FK relationship? I do not find the Limitations section in the documentation clear about this:
create table fooChild(
id int primary key not null,
md5 varbinary(16)
)
alter table fooChild add constraint FK_FOOCHILD_FOO
foreign key(md5) references FOO(md5)
Here is the answer. http://www.devx.com/tips/Tip/15397
Basically you have to ensure a function cannot return null so wrap hashbytes in isnull or coalesce.

In postgresql: Clarification on "CONSTRAINT foo_key PRIMARY KEY (foo)"

Sorry if this is a dead simple question but I'm confused from the documentation and I'm not getting any clear answers from searching the web.
If I have the following table schema:
CREATE TABLE footable
(
foo character varying(10) NOT NULL,
bar timestamp without time zone,
CONSTRAINT pk_foo PRIMARY KEY (foo)
);
and then use the query:
SELECT bar FROM footable WHERE foo = '1234567890';
Will the select query find the given row by searching an index or not? In other word: does the table have a primary key (which is foo) or not?
Just to get it clear. I'm used to specifying "PRIMARY KEY" after the column I'm specifying like this:
"...foo character varying(10) PRIMARY KEY, ..."
Does it change anything?
Why not look at the query plan and find out yourself? The query plan will tell you exactly what indexes are being used, so you don't have to guess. Here's how to do it:
http://www.postgresql.org/docs/current/static/sql-explain.html
But in general, it should use the index in this case since you specified the primary key in the where clause and you didn't use something that could prevent it from using it (a LIKE, for example).
It's always best to look at the query plan to verify it for sure, then there's no doubt.
In both cases, the primary key can be used but it depends. The optimizer will make a choice depending on the amount of data, the statistics, etc.
Naming the constraint can make debugging and error handling easier, you know what constraint is violated. Without a name, it can be confusing.