How to have constraints in graph database such as orientDB? - orientdb

I am coming from the RDBMS world. so forgive if I ask a badly phrased question.
I have a situation where I need to ensure unique or partial unique populating data inside cayley
In RDBMS such as postgres, I can build a table like this:
primary autoincrement key called id
foreignkey to person table called person_id
foreignkey to product table called product_id
foreignkey to price table called price_id
boolean field called is_removed
If i want a unique constraint such as the entire table can have a unique index such that product_id and price_id are together as a pair must be unique, I can do that.
if i want a partial unique constraint in postgres where if the is_removed is False, then the person_id, product_id, and price_id are unique.
Then if any of the foreignkeys are null, the constraints are not triggered.
How do I have something this inside a graph database such as orientDB?
My objective is to prevent creating illegal relations in the database

In orientDB you can define a schema for your database.
You have classes instead of tables.
Vertexes and edges are specialized classes.
You can define properties on classes, and define constraints on properties.
As a concrete example, the definition for the a User vertex class :
CREATE CLASS User EXTENDS V;
CREATE PROPERTY User.userId LONG;
CREATE PROPERTY User.description STRING;
CREATE PROPERTY User.screenName STRING;
CREATE PROPERTY User.lang STRING;
CREATE PROPERTY User.location STRING;
CREATE PROPERTY User.fetched BOOLEAN;
CREATE INDEX User.userId ON User(userId) UNIQUE_HASH_INDEX METADATA {ignoreNullValues: true};
CREATE INDEX User.description ON User(description) FULLTEXT ENGINE LUCENE METADATA {ignoreNullValues: true};
These are the links to the official part of the documentation about SQL and schema manipulation:
http://orientdb.com/docs/3.0.x/sql/SQL-Create-Class.html
http://orientdb.com/docs/3.0.x/sql/SQL-Create-Vertex.html
http://orientdb.com/docs/3.0.x/sql/SQL-Create-Edge.html
http://orientdb.com/docs/3.0.x/sql/SQL-Create-Index.html
http://orientdb.com/docs/3.0.x/sql/SQL-Create-Property.html

Related

how to relate many rows to a row from the same table postgresql?

consider Amazon product category architecture (one product may have 7 parent categories another might have 2). I want to build the same thing using Postgres.
A: Is there any scaleable logical way to do this? or I must consider using a graph database.
ps: the project will not be AMAZON BIG. this is a monolith project, not a microservice.
B: my thoughts are that I should have a field named parent_categories in my category table which is an array of UUIDs of categories then a field named category_id for the products table that is related to the last category parent would work.
something like this:
CREATE TABLE categories (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid (),
name VARCHAR NOT NULL,
parent_categories UUID[]
);
CREATE TABLE products (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid (),
name VARCHAR NOT NULL,
category_id UUID[],
CONSTRAINT fk_category FOREIGN KEY(category_id) REFERENCES categories(id)
);
the problem is with joining the chained categories I'm expecting a result like the below when fetching categories (I'm using node.js) and I don't know how to join every element of that array.
categories: [{
id: "id",
name: "name",
parent_categories: [{
id: "id",
name: "name"
}]
}]
This question is about relational theory.
You have a pair of tables containing id and name, that's lovely.
Discard the array attributes, and then
CREATE TABLE product_category (
product_id UUID REFERENCES products(id),
category_id UUID REFERENCES categories(id),
PRIMARY KEY (product_id, category_id)
)
Now you are perfectly set up for 3-way JOINs.
Consider adopting the "table names are singular" convention,
rather than the current plural-form names.
Add a parent_id column to categories,
so the table supports self-joins.
Then use WITH RECURSIVE to navigate
the hierarchical tree of categories.
(Classic example in the Oracle documentation
shows how manager can be used for emp
self-joins to produce a deeply nested org chart.)

Discover prisma table's primary key at runtime?

In prisma.io how do I find the name of a table's primary key? It is defined in file schema.prisma, but how to I identify the primary key of any arbitrary table at runtime, given the table's name?
So far I can find no reference to this in the documentation for Prisma Client. After instantiating PrismaClient I can find the list of tables and their column names (prisma._baseDmmf.datamodel.models), but no hint of which column(s) is the primary key.
I found an answer. I imported Prisma (in addition to PrismaClient) which provides access to Prisma.dmmf.datamodel.models which is an array of table models. Each table model includes an array of field definitions, each of which has the boolean property isId, which is true if that field is the row id.
For example:
Prisma.dmmf.datamodel.models[1].fields[0].isId
The names of each table and each field are string properties:
Prisma.dmmf.datamodel.models[1].name == 'Assets'
Prisma.dmmf.datamodel.models[1].fields[0].name == 'AssetId'
Hope this helps someone.

understanding an inheritance in Postgres; why key "fails" in insert/update command

(One image, tousands of words)
I'd made few tables that are inherited between themselves. (persons)
And then assign child table (address), and relate it only to "base" table (person).
When try to insert in child table, and record is related to inherited table, insert statement fail because there is no key in master table.
And as I insert records in descendant tables, records are salo available in base table (so, IMHO, should be visible/accessible in inherited tables).
Please take a look on attached image. Obviously do someting wrong or didn't get some point....
Thank You in advanced!
Sorry, that's how Postgres table inheritance works. 5.10.1 Caveats explains.
A serious limitation of the inheritance feature is that indexes (including unique constraints) and foreign key constraints only apply to single tables, not to their inheritance children. This is true on both the referencing and referenced sides of a foreign key constraint. Thus, in the terms of the above example:
Specifying that another table's column REFERENCES cities(name) would allow the other table to contain city names, but not capital names. There is no good workaround for this case.
In their example, capitals inherits from cities as organization_employees inherits from person. If person_address REFERENCES person(idt_person) it will not see entries in organization_employees.
Inheritance is not as useful as it seems, and it's not a way to avoid joins. This can be better done with a join table with some extra columns. It's unclear why an organization would inherit from a person.
person
id bigserial primary key
name text not null
verified boolean not null default false
vat_nr text
foto bytea
# An organization is not a person
organization
id bigserial not null
name text not null
# Joins a person with an organization
# Stores information about that relationship
organization_employee
person_id bigint not null references person(id)
organization_id bigint not null references organization(id)
usr text
pwd text
# Get each employee, their name, and their org's name.
select
person.name
organization.name
from
organization_employee
join person on person_id = person.id
join organization on organization_id = organization.id
Use bigserial (bigint) for primary keys, 2 billion comes faster than you think
Don't enshrine arbitrary business rules in the schema, like how long a name can be. You're not saving any space by limiting it, and every time the business rule changes you have to alter your schema. Use the text type. Enforce arbitrary limits in the application or as constraints.
idt_table_name primary keys makes for long, inconsistent column names hard to guess. Why is the primary key of person_address not idt_person_address? Why is the primary key of organization_employee idt_person? You can't tell, at a glance, which is the primary key and which is a foreign key. You still need to prepend the column name to disambiguate; for example, if you join person with person_address you need person.idt_person and person_address.idt_person. Confusing and redundant. id (or idt if you prefer) makes it obvious what the primary key is and clearly differentiates it from table_id (or idt_table) foreign keys. SQL already has the means to resolve ambiguities: person.id.

Database design with composite types in postgresql

How to refer another table built from composite type in my table.
I am trying to setup a database to understand postgresql and its Object oriented features.
The statement is as follows : There are multiple companies which can have board members.
Each company can own another company or a person can own that company too.
This is the type of database design I am looking for.
create type companyType(
name: VARCHAR,
boardMembers : personType[],
owns: companyType[]
)
create type personType(
name: VARCHAR,
owns: companyType[]
)
Create table company as companyType
Create table person as personType
I understand that I cannot self reference the companyType so I will probably move this another table.
My question is, when I am trying to insert into say company type, how do i insert list of person table objects as foreign key ?
Would making a column 'id' in each table and giving it type SERIAL work to use it as a foreign key?
That is not a relational database design, and you won't get happy with it.
Map each object to a table. The table columns are the attributes of the object. Add an artificial primary key (id bigint GENERATED ALWAYS AS IDENTITY). Don't use composite types or arrays.
Relationships are expressed like this:
If the relationship is one-to-many, add a foreign key to the "many' side.
If the relationship is many-to-many, add a "junction table" that has foreign keys to both tables. The primary key is the union of these foreign keys.
Normalize the resulting data model to remove redundancies.
Sprinkle with unique and check constraints as appropriate.
That way your queries will become simple, and you can use your database's features to make your life easier.

Entity Framework map using Foreign Key and type field

This is a simplified version of the problem I'm facing. Basically, I have an existing database with code-first Entity Framework on top of, and there are several tables where I see an ObjectId and ObjectType field. Depending on the ObjectType, the table can be joined to one of several other disparate tables which do not share a hierarchy.
For example, given the following database tables:
CREATE TABLE BarCode
(
Id int NOT NULL PRIMARY KEY,
ObjectType int NOT NULL,
ObjectId int NOT NULL,
BarCodeValue varchar(20) NOT NULL,
)
CREATE TABLE Person
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20),
)
CREATE TABLE Package
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20),
)
I might see rows in the BarCode table with an ObjectType of 1, which correspond to Person records, or rows with an ObjectType of 2, which correspond to Package records.
In Entity Framework, how do I set up a mapping so that the Person entity can have a BarCode and the Package entity can have a Barcode? I don't see where the Map() method allows you to specify any fields other than the foreign key field. Like I said, there's really no hierarchy among these objects, it's more that they share a common attribute. Sort of like decorating a class with an interface vs. having it inherit from something.