unique constraint in yang models - ietf-netmod-yang

if I have the following model
devices {
device {
key id;
interfaces {
interface {
key id;
unique name;
}
}
}
}
which data is valid or invalid according to yang's key and unique specification ?
1. devices/device=1/interfaces/interface=1; name = a
2. devices/device=1/interfaces/interface=1; name = b // key violation
3. devices/device=1/interfaces/interface=2; name = a // unique violation
4. devices/device=2/interfaces/interface=1; name = a // unique violation ?
supposing I store the 'interface' objects in a relational table and mark name as unique column, I cannot have both data row 3 and 4. Is that what the spec is meaning ?
or,
can I interpret the uniqueness or key constraint as , unique resource path ?
If I do so, the following rows of data do not conflict because they are two different resource urls, because they belong to different devices.
devices/device=1/interfaces/interface=2; name = a
devices/device=2/interfaces/interface=2; name = a
what is the right interpretation ? globally unique vs unique within the list parent ?

The correct answer is probably: it is unclear for nested lists.
The "unique" constraint specifies that the combined values of all the
leaf instances specified in the argument string, including leafs with
default values, MUST be unique within all list entry instances in
which all referenced leafs exist or have default values.
RFC7950, Section 7.8.3.
The "list" statement is used to define an interior data node in the
schema tree. A list node may exist in multiple instances in the data
tree. Each such instance is known as a list entry.
RFC7950, Section 7.8.
The same text appears in RFC6020 (YANG version 1).
If you interpret it strictly, you have no choice: you have to make all list entries have a unique name globally in order to fulfill the constraint. Note that the same would apply to list's key, due to similar wording.
It is unclear whether this was the intention though.
RFC6110, which deals with YANG based instance validation using existing XML technologies, interprets it as unique within parent and it was created by the same WG: it uses the preceding-sibling:: XPath axis to enforce the constraint, which does not pick up device/id=2 interface entries inside device/id=1, since device/id=1/interfaces/interface instances and device/id=2/interfaces/interface instances are not siblings in an XML document.
Note that RFCs are not immune to bugs.

The scope of unique is the same as the scope of key. That is, in your example, different devices have separate lists of interfaces. In the same way both devices '1' and '2' have an interface '1', devices '1' and '2' can have interfaces with name 'a'.
Note that, unlike key, unique can reference descendant nodes. If one wanted to make the names unique across devices then one could use unique within the device list:
list device {
key 'id';
unique 'interfaces/interface/name';
...
}

Related

mapping generalization constraints to sql (STI approcach)

I'm trying to model the following relationships between entities, mainly consisting of a partial, disjoint generalization.
original EERD
'mapped' to relational
Since I didn't need the subclasses to have any particular attributes I decided to use the "single table inheritance" approach, added the "type" field and moved the relationships towards the parent.
After that I had two choices to make:
1- type for the "business type" attribute
2- way to constraint participation to at most one of the 4 relationships based on the type attribute
For the sake of portability and extensibility I decided to implement no.1 as a lookup table (rather than enum or a hardcoded check).
About no.2 I figured the best way to enforce participation and exclusivity constraints on the four relationships would be a trigger.
The problem is that now I'm not really sure how to write a trigger function; for instance it would have to reference values inserted into business type, so I'd have to make sure those can't be changed or deleted in the future.
I feel like I'm doing something wrong so I wanted to ask for feedback before going further; is this a suitable approach in your opinion?
I found an interesting article describing a possible solution: it feels a bit like an 'hack' but it should be working
(it's intended for SQL Server, but it can be easily applied in postgres too).
EDIT:
It consists in adding a type field to the parent table, and then have every child table reference said field along with the parent's id by using a foreign key constraint (a UNIQUE constraint on this pair of fields has to be added beforehand, since FKs must be unique).
Now in order to force the type field to match the table it belongs to, one adds a check constraint/always generated value ensuring that the type column always has the same value
(eg: CHECK(Business_type_id = 1) in the Husbandry table, where 1 represents 'husbandry' in the type lookup table).
The only issue is that it requires a whole column in every subclass, each containing the same generated value repeated over and over (waste of space?), and it may fall apart as soon as the IDs in the lookup table are modified

Deciding primary key for DynamoDB

I have 3 fields to store in DynamoDB: identity-1, identity-2, score.
identity-1 and identity-2 are always unique in the table, i.e. no two entries can have same identity-1 or identity-2.
We want to allow entries to either have one of identity-1 or identity-2 or have both. Example:
identity-1
identity-2
score
a1
b1
s1
a2
s2
b3
s3
Access patterns are as follows:
Query identity-2 from identity-1
Query score from identity-1
Query score from identity-2
How do I define primary key in such case?
This is a "many:1" problem and there's a few ways to tackle it with DynamoDB. The simple answer here is to leverage Global Secondary Indexes (GSI). For every "identity" you wanted to do a direct look up from, you'd create a GSI.
GSI-1 would include Identity-1 as the hash key and you'd include Identity-2 and any other identities as a non-key attribute to include. You'd create a GSI for each identity you wanted to query directly on. You could also include the score as a non-key attribute if you wanted to directly look up score from any identity without having to resolve to the primary key (which we'll talk about).
The thing to consider with GSI's, though, is that they consume extra storage and throughput. If you create a GSI which includes all your attributes for every identity, you'd be paying for an additional copy of your table for each identity.
The other issue, so far, is that you haven't chosen a Primary Key for your table. You'll need a field to be your primary key and if none of your identities is non-nullable, you'll need a field which will be. It's often convenient to just call it what it is, so we'll call it pk.
You've got a few choices for pk here. Once is to define pk as a composite of your identities. For example: item.pk = item["identity-1"] || item["identity-2"]. Then you could do a query on the table for the identity == pk and if you don't find anything, you could then look up the index for the given identity. This works fine for your simple example, but as you wanted to do more complex things (such as many different identity types), you might find it to be a bit of a headache.
From past experience, my recommendation would be to adjust your approach slightly, however, and have an "users" table and a "scores" table. "users" would have a pk of a guid unique for every user and all their identities (call it "user_id"), you could then create a GSI for that table for every identity back to user_id. Then scores would then use "user_id" as the pk as well with no need for an index. Your application would always resolve to a "user_id" when a user was logged in or otherwise identified - then you can search for score without needing to track identity and you can look up all the associated identities or other user information without needing to create a very "fat" index of every identity->every other identity.

Apache Ignite generated key for cluster but no key class

I used Ignite Web Console to generate a cluster configuration for an existing database. One of the tables in question has no key--it consists of two columns, both integers, neither of which is a key. There is a foreign key constraint that one of the columns must exist in another table, but I don't especially care about that.
In the generated cluster xml, each of the two columns is represented as a value field. These two fields match up with the generated POJO class as well. However, in the "keyType" field of the cluster config, it references a generated key class that, as far as I can tell, does not exist. If the POJO class for the table is Foo, then the key class is written down as FooKey, but this class does not exist in the project, and there is no definition for what fields would be in the key.
What am I supposed to do when referencing this cache? Do I need to create an implementation of this key class myself? When I make calls to the cache, does it need to be in the Entry format? How does the key-value store work when there is no key in the original table?
I think you’ll need to add these fields manually to "keyType". In order to do this find a model in Advanced -> SQL Scheme, then select two columns in "Key fields" dropdown menu. This will generate the FooKey.

Does a weak entity need a partial key?

Does a weak entity need a partial key? Or can you just use its parent key as its primary key.
i.e Order and OrderItem. Order has a PK OrderPK, whilst OrderItem has no partial key.
Is this considered bad practice?
The OrderItem table should have an OrderID field that makes a FK reference back to the Orders table. This assures each item is for a valid order.
Then there is usually another field with distinguishes each item which would be used together with the OrderID field to form the primary key for the item.
This could be an intrinsic value or values that is unique for each item within an order. SKU or PartNum might be just such a value, assuming that multiple occurrences of the same item would be merged into one entry. To find this value, just ask yourself what minimum amount of data would you need to uniquely identify one item from another within the same order. However, it may not be possible. A disadvantage of this scheme is that you could be using dynamic data for a key field. The SKU of a particular item could well change some time in the future.
Or there could be a sequential value (1, 2, 3,...) for each item in an order. A disadvantage with this scheme is the sequential values cannot be system generated. Each sequence is unique for each order and this must be generated by trigger or application code.
Or there could be a system-generated sequential value unique to all the items for all the orders and this field could be the lone primary key. Per-order sequential values could still be generated by row_number functions in queries, but this means a particular item could have different values in different queries. That may or may not be a problem.
At this point, only you know enough about your system to choose the best option. But it is generally necessary for users to be able to select one specific item of one specific order, so some sort of key definition for each item is usually necessary.

Using a string vs an id as a foreign key in Mongodb

I have a collection users whose documents will belong to a company (and each company can have many users). Because I set a unique index on the company name, can I use the name as the foreign key inside the user document, or is it recommended to use the id instead?
If name is unique and is guaranteed to never change, then you can use it, no problem. Although there were cases in my practice when names turned out to be not-so-unique and not-so-immutable (damn requirement changes). So, just to be extra safe, use the id.