On Thursday, 10 June 2021 at 19:25:02 UTC+10, Derek Ignatius Asirvadem wrote:
On Thursday, 10 June 2021 at 02:43:14 UTC+10, Nicola wrote:
On Thursday, 10 June 2021 at 02:43:14 UTC+10, Nicola wrote:Yes, of course.
Among the rest, the model declares:
Person is 0-to-1 Employee
The textual predicates do not state it explicitly, but the model also declares the converse relationship:
Employee is 1 Person
To be Clear
Besides:
Employee is an exclusive basetype, one of {FullTime, Consultant}
Your predicates do not state is explicitly, but the verbal phrase for exclusive subtyping is "is". So, the model also declares:
EmployeeFullTime is 1 Employee
EmployeeConsultant is 1 Employee
"Each Basetype and Subtype pair should be perceived as a single logical unit" (same doc., p. 5).
Now before we get into the next set of Qs. Stop and take a breath. Consider this. As an academic, you are heavily (and I mean heavily) programmed into thinking in terms of Fragments (as opposed to Atoms); single level (as opposed to multiple); simple
So, it's fair to say, e.g., that an
EmployeeFullTime has a JobTitle and an EmployeeDate, and I can sensibly query for the job titles of all full time employees. JobTitle and EmployeeDate are descriptors of EmployeeFullTime.
But Person and Employee should not be perceived as a single logical
unit: as per your discussion in §3, that would be incoherent.
So, does
an Employee have a NameLast or a BirthDate?
If so, what in the model
does entitle me to state that?
For comparison, suppose that there is also a Hunting License entity, and
a relationship between Person and Hunting License:
Person has 0-to-1 Hunting License
Certainly, I would not say that a Hunting License has a NameLast or
a BirthDate or that NameLast and BirthDate are descriptors of Hunting License.
We can *count* on the fact that, from the child, any attribute in a parent hierarchy is 1::1.
On Thursday, 10 June 2021 at 19:25:02 UTC+10, Derek Ignatius Asirvadem wrote:
Thus any Binary Predicate can be read “two ways”, and only the *Verb*, not the full text, is required on the relation line, because each of the binaries is diagrammatically connected. Usually only the parent->child *Verb* is shown, and the converseis simple enough to determine [by reversal of the elements] by the reader.
3. In general, I would stop using OO/OOP/ORM terms when dealing with data and databases, and specifically use Relational terms when the database is Relational. Use of their terms implies their meaning, which is crippled, because OO is crippled (ambiguous; not a Standard; 420 notations; nothing clearly defined; etc). I deal with OO/OOP/ORM people all the time, and they appreciate that I do NOT use their terms, that I use Relational terms, which are rock solid. Just think about how stupid /
Read /Unskilled and Unaware/ by Krüger and Dunning 1999.
Now that you have declared that the previous thread. is resolved, I do not understand why /Incomplete/ is still hanging around. Recall, there are two meanings: the original IDEF1X; and the common promoted by ERwin. The former being illegal.
On Thursday, 10 June 2021 at 19:25:02 UTC+10, Derek Ignatius Asirvadem wrote:
2.
This is an error:
__Person is described by ( SexCode, Title )
__Person is described by ( NameLast, NameFirst, Initial, BirthDate, BirthCountryCode, BirthPlace, Sex, Title )
HunterLicence
Certainly, I would not say that a Hunting License has a NameLast or
a BirthDate or that NameLast and BirthDate are descriptors of Hunting
License.
Why not ?
(I am assuming you are not being silly about the wording, but chasing meaning; declarative meaning.)
A Hunting licence is not a piece of paper gambolling around in the Tyrolian Alps (Fragment).
__If it were a Fragment, sure, you should not say that
__But a HuntingLicence is not a Fragment
A Hunting licence is a /Power to Act/, that is given to a Person (not animal, not thing), it does not exist
independently, it exists only in the context of Person.
Predicates, as modelled:
__HuntingLicence is dependent
__HuntingLicence is dependent on 1 Person
__HuntingLicence is identified by 1 Person
__HuntingLicence is 1 Person
Strictly, the entity is not HuntingLicence but Person-HuntingLicence.
Which is the real world, HuntingLicence is not a piece of paper (the Physical), but an option of Person (the Logical,
the Real). (Or /a/ progression of Person in the fullness of definition of Person).
So, you are saying that a 0-to-1 relationship is essentially always
"is".
On Friday, 11 June 2021 at 18:35:42 UTC+10, Nicola wrote:
So, you are saying
that a 0-to-1 relationship is essentially always "is”.
The key in the parent and the key in the child is the same, so theparent and the child must describe the same "molecule", as you call it.
So, using another verb is just for convenience.
The relationship reads "Problem has a Composer_2".
But, that really means "Problem is a Problem-[With]-Composer_2", doesn't it?
Hence, Composer_2 is an optional attribute of a Problem,
and Problem-Composer_2 is described by a Name and a Score, just as Problem is. Right?
The key in the parent and the key in the child is the same,
so the parent and the child must describe the same "molecule"
Whoa. You are responding to the first item that perturbed you.
Please read again, there is a bigger item coming up, or stated
otherwise, the item is bigger than you think.
3. The Verb on the relation line is specific, read in both directions.
The generic Verb for any child-to-parent relation is /is/.
Think Codd’s 3NF & FFD only.
<FK in Child> <Verb> 1 <Parent(PK)>
The proper <Verb> is specific.
The generic <Verb> is /is/.
The key in the parent and the key in the child is the same, so theparent and the child must describe the same "molecule", as you call it.
Am I understanding right?
Not quite.
Two separate concepts. Don’t conflate them.
In an Identifying hierarchy, the child has all the keys for its
lineage; in a Non-Identifying hierarchy, the child has just the one
key for its single-level parent.
That Bridge problem is from my days of hard labour at TTM gulag.
On Saturday, 12 June 2021 at 04:48:27 UTC+10, Nicola wrote:
On 2021-06-11, Derek Ignatius Asirvadem wrote:
Whoa. You are responding to the first item that perturbed you.
Please read again, there is a bigger item coming up, or stated
otherwise, the item is bigger than you think.
No, I have read all of your replies. Then, I have replied to the point
for which I wanted a clarification. This post of yours provides the
required clarification (and more).
In particular:
3. The Verb on the relation line is specific, read in both directions.
The generic Verb for any child-to-parent relation is /is/.
Think Codd’s 3NF & FFD only.
<FK in Child> <Verb> 1 <Parent(PK)>
The proper <Verb> is specific.Finally I understand the sense in which you use those verbs.
The generic <Verb> is /is/.
The key in the parent and the key in the child is the same, so theparent and the child must describe the same "molecule", as you call it.
Am I understanding right?
Not quite.
Two separate concepts. Don’t conflate them.
Ok, from your extensive explanation,
I've also got the meaning in which
you use the term "molecule".
In an Identifying hierarchy, the child has all the keys for its
lineage; in a Non-Identifying hierarchy, the child has just the one
key for its single-level parent.
That's a prominent remark, as simple as it is. When you learn that, you
(a) understand why IDEF1X distinguishes between identifying and non-identifying, and (b) you look at the diagrams in a novel way, immediately perceiving the (join) relationships between entities that
are far apart. At least, this is what I felt when I first understood
that.
That's a prominent remark, as simple as it is.
3. The Verb on the relation line is specific, read in both directions.Finally I understand the sense in which you use those verbs.
The generic Verb for any child-to-parent relation is /is/.
Think Codd’s 3NF & FFD only.
<FK in Child> <Verb> 1 <Parent(PK)>
The proper <Verb> is specific.
The generic <Verb> is /is/.
But is it not normal English ?
I will give you one more increment.
- All tables/facts are Atoms
- Only a root Atom can be the start of a Molecule that is relevant (perceiving a Molecule in the middle of a tree is hopeless).
--- that means a Hierarch (independent, square corners)
--------
In an Identifying hierarchy, the child has all the keys for its
lineage; in a Non-Identifying hierarchy, the child has just the one
key for its single-level parent.
That's a prominent remark, as simple as it is. When you learn that, you
(a) understand why IDEF1X distinguishes between identifying and
non-identifying, and (b) you look at the diagrams in a novel way,
immediately perceiving the (join) relationships between entities that
are far apart. At least, this is what I felt when I first understood
that.
That is what I meant when I said /the item is bigger than you think/.
I knew a big AHA was coming. But I was shocked that you did not know
that, and surprised again, when several increments of explanation were required.
By the way, I have developed a tighter Standard, IDEF1R. Therein
I have eliminated this problem of not comprehending this issue.
(Modelling instructions)
(Modelling instructions)
Done.
Doc updated:
____ https://www.softwaregems.com.au/Documents/Article/Normalisation/Bridge%202.pdf
I have used the IDEF1R symbol for ExclusiveSubtype, with the IDEF1X in
the left margin for comparison. Please choose.
(Modelling instructions)
Done.
Doc updated:
____ https://www.softwaregems.com.au/Documents/Article/Normalisation/Bridge%202.pdf
On Saturday, 12 June 2021 at 19:04:17 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:
3. The Verb on the relation line is specific, read in both directions. >> > The generic Verb for any child-to-parent relation is /is/.Finally I understand the sense in which you use those verbs.
Think Codd’s 3NF & FFD only.
<FK in Child> <Verb> 1 <Parent(PK)>
The proper <Verb> is specific.
The generic <Verb> is /is/.
But is it not normal English ?
As a non-native speaker, there will always be nuances of the English language I won't grasp.
On Saturday, 12 June 2021 at 17:07:38 UTC+10, Derek Ignatius Asirvadem wrote:
[... I trust you understand and appreciate ...]
____ FOPC[ Relation ]-->RM[ Identifying | Non-Identifying ]-->IDEF1X-->{ Solid | Dashed }
____ FOPC[ Predicate ]-->RM[ PredicateTerse ]-->IDEF1X-->[ PredicateGraphic ]
On Saturday, 12 June 2021 at 23:12:07 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:
What issues do you see with a discriminator assigning more than one
value to a subtype?
primary or secondary -> Composer
solver -> Solver
Also, I don't understand this sentence:
The cumbersome <Role.PK> is replaced with <Role>.
I haven't put Role in the primary key.
Composer(Composer.PersonId ProblemName)
On Saturday, 12 June 2021 at 18:22:59 UTC+10, Nicola wrote:
Then, Solver_Not_Composer, Solver_Not_JointComposer, and JointComposer_Not_Composer all reduce to a single check in StakeHolder.
On Saturday, 12 June 2021 at 23:45:52 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:
One more thing. Your constraints are implemented as CONSTRAINT.. CHECK clauses. Those are checked before every insert or update. A constraint
such Solver_Max_4 would correctly prevent you from inserting a fifth
solver. But it would also prevent you to update an existing solver when there are already four of them.
Triggers would provide a trivial solution for that, but AFAIK you don't
use them (and I agree with you on avoiding them as much as possible).
So, how do you deal with that? Delete plus insert, instead of update?
On Sunday, 13 June 2021 at 11:48:12 UTC+10, Derek Ignatius Asirvadem wrote:
In the next iteration, I will give ComposerType. (This is modelling, yes, we have many iterations). You tell me what you want.
[etc]
On Saturday, 12 June 2021 at 23:12:07 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:
What issues do you see with a discriminator assigning more than one
value to a subtype?
I think you mean /What issues do you see with a discriminator being overloaded (more than the range of subtype Discriminators) ?/
The issue here is nothing to do with Discriminators or Subtypes. It
has to do with overloading.
So in the previous model 12.2 Jun 21, I as DBA policeman re what goes
into the db, allowed your Role, but insisted on the required
Discriminator Staketype. In the next iteration, I will give
ComposerType. (This is modelling, yes, we have many iterations). You
tell me what you want.
Also, I don't understand this sentence:
The cumbersome <Role.PK> is replaced with <Role>.
I haven't put Role in the primary key.
Not the column name Role, but the /RM/ concept of Role.
On Saturday, 12 June 2021 at 18:22:59 UTC+10, Nicola wrote:
Then, Solver_Not_Composer, Solver_Not_JointComposer, and
JointComposer_Not_Composer all reduce to a single check in
StakeHolder.
Implementation standards again.
Mine require each CHECK constraint to do just one logical thing,
generally that means one <LogicalCondition> per constraint.
While I am here,let me point out something about naming. For meaning
and brevity, the constraint name is:
__ Secondary_Max_1
The table prefix is excluded in the model at the table entry, but
demanded in the physical (otherwise you will never find the constraint
in the list of constraints), and is so listed at the expansion at the
bottom:
__ Composer_Secondary_Max_1
Along with the full CHECK condition given in pseudo-sql (my notation,
which you have seen before):
__ CHECK Composer[ @Primary ] EXISTS
__ AND
__ CHECK Composer[ @Secondary ] NOT EXISTS
See, even typing that exposes that it is incorrect. Ah, the wonder of
the iterations in data modelling.
__ CHECK Composer.IsPrimary[ @ProblemName ] EXISTS
__ AND
__ CHECK ( Composer.IsPrimary[ @ProblemName ] = 0 ) NOT EXISTS
For a bit of a write-up on naming, see this post. SO actively
suppresses the truth, same as the /RM/ saboteurs:
__ https://stackoverflow.com/a/4703155/484814
On Saturday, 12 June 2021 at 23:45:52 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:One more thing. Your constraints are implemented as CONSTRAINT.. CHECK
clauses. Those are checked before every insert or update. A constraint
such Solver_Max_4 would correctly prevent you from inserting a fifth
solver. But it would also prevent you to update an existing solver when
there are already four of them.
Triggers would provide a trivial solution for that, but AFAIK you don't
use them (and I agree with you on avoiding them as much as possible).
Absolutely.
I have never written a trigger in my life.
I have examined and replaced over 2,000 triggers in customer databases
with proper DDL and Transactions.
So, how do you deal with that? Delete plus insert, instead of update?
That is a question that should be answered fully. Considerations.
4. Not on my platform.
The CHECK constraint is fired for UPDATE only if a column named in the constraint is affected. __ In this case, no columns are named, meaning
it is not CHECKed on UPDATE __ And I can force the constraint to be
CHECKed by naming a column (There is a huge value in commercial SQL platforms, that the freeware crowd cannot even dream of.)
Example from MS/SQL, which is the same as mine in this issue: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cdb87a2e-41ce-4a97-8a14-3f218eb00721/function-check-constraint-ignored?forum=transactsql
5. For others.
In general, yes, DELETE+INSERT.
Note that one should be used to that because UPDATE any Key component
is not permitted, it must be DELETE+INSERT, in a Transaction of
course, that moves the entire hierarchy belonging to the Key.
I forgot to mention, of course the documents is updated.
Example from MS/SQL, which is the same as mine in this issue:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cdb87a2e-41ce-4a97-8a14-3f218eb00721/function-check-constraint-ignored?forum=transactsql
Funny example. The OP's constraint wouldn't work even if the constraints
were triggered,
[...]
I do not see how you could prevent them with CONSTRAINT.. CHECK.
[...]
I do not see other ways.
On Monday, 14 June 2021 at 01:13:54 UTC+10, Nicola wrote:
On 2021-06-13, Derek Ignatius Asirvadem wrote:
On Saturday, 12 June 2021 at 23:12:07 UTC+10, Nicola wrote:
See, even typing that exposes that it is incorrect. Ah, the wonder of
the iterations in data modelling.
__ CHECK Composer.IsPrimary[ @ProblemName ] EXISTS
__ AND
__ CHECK ( Composer.IsPrimary[ @ProblemName ] = 0 ) NOT EXISTS
I think that you still have a typo there. The second clause should read:
[AND] CHECK ( Composer.~~~IsSecondary~~~[ @ProblemName ] = 0 ) NOT EXISTS
For a bit of a write-up on naming, see this post. SO actively
suppresses the truth, same as the /RM/ saboteurs:
__ https://stackoverflow.com/a/4703155/484814
I know that post. I found it while searching for naming standards some
time ago. Good advice, generally speaking, although I do not follow all
of it. For instance, I find the recommendation for large subject areas
(use table prefixes) rather odd, when logical separation is precisely
the purpose of schemas (CREATE SCHEMA). The advice is good for platforms
not supporting schemas, such as MySQL, though.
On Saturday, 12 June 2021 at 23:45:52 UTC+10, Nicola wrote:
On 2021-06-12, Derek Ignatius Asirvadem wrote:One more thing. Your constraints are implemented as CONSTRAINT.. CHECK
clauses. Those are checked before every insert or update. A constraint
such Solver_Max_4 would correctly prevent you from inserting a fifth
solver. But it would also prevent you to update an existing solver when >> there are already four of them.
4. Not on my platform.
The CHECK constraint is fired for UPDATE only if a column named in the constraint is affected.
__ In this case, no columns are named, meaning it is not CHECKed on UPDATE __ And I can force the constraint to be CHECKed by naming a column
(There is a huge value in commercial SQL platforms, that the freeware crowd cannot even dream of.)
Ok, I didn't know that.
Example from MS/SQL, which is the same as mine in this issue: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cdb87a2e-41ce-4a97-8a14-3f218eb00721/function-check-constraint-ignored?forum=transactsql
Funny example. The OP's constraint wouldn't work even if the constraints were triggered ...
Ironically (since you posted that), the first reply in that thread recommends: "using scalar UDFs that read the database in a CHECK
constraint is not a good practice. Triggers are simpler and more
useful". Indeed, that example would be solved easily with triggers.
CHECK is BIT/BOOLEAN. So at best, a Function called be a CHECK should be BIT/BOOLEAN.
Alternatively, you'd have to revoke writes and use stored procedures to perform semantically meaningful operations.
Yes, I know you do that.
I do not see other ways.
5. For others.
In general, yes, DELETE+INSERT.
Note that one should be used to that because UPDATE any Key component
is not permitted, it must be DELETE+INSERT, in a Transaction of
course, that moves the entire hierarchy belonging to the Key.
That is because in your experience, cascading updates (UPDATE ...
CASCADE), are inefficient, right?
On Monday, 14 June 2021 at 05:30:34 UTC+10, Nicola wrote:
On 2021-06-13, Nicola wrote:
Example from MS/SQL, which is the same as mine in this issue: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cdb87a2e-41ce-4a97-8a14-3f218eb00721/function-check-constraint-ignored?forum=transactsql
Funny example. The OP's constraint wouldn't work even if the constraints were triggered,No no, of course it can be done with constraints. I got confused by the
[...]
I do not see how you could prevent them with CONSTRAINT.. CHECK.
[...]
I do not see other ways.
fact that the OP defines one function to implement different
constraints.
A good example of issues arising from conflating different conditions.
I think that you still have a typo there. The second clause should read:[...]
[AND] CHECK ( Composer.~~~IsSecondary~~~[ @ProblemName ] = 0 ) NOT EXISTS
So this:
__ CHECK ( Composer.IsPrimary[ @ProblemName ] = 0 ) NOT EXISTS
checks that a Secondary does not exist.
Example from MS/SQL, which is the same as mine in this issue:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cdb87a2e-41ce-4a97-8a14-3f218eb00721/function-check-constraint-ignored?forum=transactsql
Ironically (since you posted that), the first reply in that thread
recommends: "using scalar UDFs that read the database in a CHECK
constraint is not a good practice. Triggers are simpler and more
useful". Indeed, that example would be solved easily with triggers.
1. Triggers are simply stupid, maintenance is horrendous. Total
unnecessary in the real world of Open Architecture,
[...]
Using Functions that are called by CHECK Constraints is pedestrian,
the world has been doing it since 2007. CHECK can only check the
inserted row. CHECK+Function can check other rows in the table, or any
other table.
On Monday, 14 June 2021 at 17:03:04 UTC+10, Nicola wrote:
On 2021-06-14, Derek Ignatius Asirvadem wrote:
1. Triggers are simply stupid, maintenance is horrendous. Total unnecessary in the real world of Open Architecture,
[...]
Using Functions that are called by CHECK Constraints is pedestrian,
the world has been doing it since 2007. CHECK can only check the
inserted row. CHECK+Function can check other rows in the table, or any other table.
For platforms where that is true, I totally agree.
I can code that way in PostgreSQL, and it is an elegant approach. It
even appears to work in simple tests, which is nice because I can try
that approach. Unfortunately, it is not really supported (it fails
under concurrent loads
—have fun with this comment), so triggers are the only
alternative in most cases. But you get what you pay for, right?
On the other hand, a *disciplined* use of triggers, restricted to such constraints, is fine. It achieves the same results as declarative constraints, with some added flexibility and efficiency, because you can specify exactly which operations on which columns under which conditions should fire the trigger. Error reporting is just as expressive, or more (custom messages). The trigger shows up just as a constraint associated
to a table when you inspect the table metadata. Just slightly more
verbose to write.
Same as using prefixes because you have no schemas. Not ideal, but still workable.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 430 |
Nodes: | 16 (2 / 14) |
Uptime: | 153:21:50 |
Calls: | 9,067 |
Calls today: | 4 |
Files: | 13,402 |
Messages: | 6,020,220 |