dbTalk Databases Forums  

What are the differences between the terms, CANDIDATE KEY, PRIMARY KEY, SUPER KEY, COMPOSITE KEY?

comp.databases.theory comp.databases.theory


Discuss What are the differences between the terms, CANDIDATE KEY, PRIMARY KEY, SUPER KEY, COMPOSITE KEY? in the comp.databases.theory forum.



Reply
 
Thread Tools Display Modes
  #31  
Old   
dawn
 
Posts: n/a

Default Re: MV Keys - 02-26-2006 , 01:25 PM







mAsterdam wrote:
Quote:
dawn wrote:
mAsterdam wrote:

dawn wrote:

... What does it mean that a list is a key? If
I change one value in the list, does that make it a new key? I would
think so.

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)


Yes, I too often mix sets & lists when I think in terms of the MV data
model, which has only list attributes in which conceptual sets & lists
are both implemented.


Really? Are sets implemented as well?
In MV, functions (sets) are like files with a primary key. They permit
list values for attributes as well as single values. All attributes
are ordered and the values within them are ordered and the sub-values
within them are ordered. It looks very much like a compact version of
XML with "markers" (specific ascii codes) separating records,
attributes, values, sub-values instead of metadata strewn throughout.
The other difference is that you don't go more than a couple of levels
deep in the nesting in MV compared to the possibilities for nesting in
XML. Cache' (MUMPS) has more nesting. I have never encountered a need
for it and it seems to help with conceptual simplicity not to have more
nesting available within a single file.

Quote:
I thought it was more like this:
When you have a model only supporting lists (e.g. XML) you have
no choice but to implement any multi-value thingy as a list - wether
you initially thought of it as a set or not.
Yes, that is precisely the case with MV, which I think of conceptually
much like an XML database without the performance and other issues. If
the toolsets were a bit more modern (I'm still trying to figure out
what such improvements might be needed), it would much more obviously
meet the needs of today's s/w development than other tools, I think.
Cheers! --dawn



Reply With Quote
  #32  
Old   
mAsterdam
 
Posts: n/a

Default Re: MV Keys - 02-26-2006 , 01:43 PM






David Cressey wrote:
Quote:
"mAsterdam" <mAsterdam (AT) vrijdag (DOT) org> wrote


If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)


In other words, an onion and mushroom pizza is different from a mushroom and
onion pizza.

Here we go again.
Yeah, ehrm well... Is this issue closed? Is there a nice solution?

In e.g. XML the basic assumption is that order has meaning, in SQL
it is that order has no meaning. Historically (XML coming from
a document heritage, SQL from experiments with relational
products) this makes sense, but I would prefer it if one could
choose wether order is meaningful/worth preserving/relevant or
not - instead of being pushed into one way of thinking or another
because of the background of the product at hand.


Reply With Quote
  #33  
Old   
Bob Hairgrove
 
Posts: n/a

Default Re: MV Keys (was: Key attributes with list values) - 02-26-2006 , 01:47 PM



On 26 Feb 2006 08:19:50 -0800, "Marshall Spight"
<marshall.spight (AT) gmail (DOT) com> wrote:

Quote:
mAsterdam wrote:
dawn wrote:
... What does it mean that a list is a key? If
I change one value in the list, does that make it a new key? I would
think so.

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)

Sure. If you change the order of the bits in the int,
that makes it a new key as well.

If you make a logical change to the value, it's a different value.
(Likewise, if the logical value stays the same but something
else changes, it's the same value.)
It's not quite that simple. As David pointed out, a "mushroom and
onion pizza" is not necessarily different than an "onion and mushroom
pizza". But the ordering of the bits in an integer is significant,
whereas the ordering of ingredients for a pizza isn't (although I'd
definitely want to make the crust before I put the tomato sauce on
it<g>).

One of the fundamental things in RM is that the Cartesian join of two
relations is commutative. Think about the implications of this when
trying to decide what requirements a MV key would have to fulfill.

In Joe Celko's book "SQL for Smarties", there is an example of a
schema for an airline scheduling system which he uses to illustrate
DKNF (starts at the bottom of p. 35). How would someone model this in
a MV database? In this and similar threads here, when people talk
about the virtues of MV vs. RM, there is a perceived (by me) lack of
any real-world examples on the MV side that go beyond trivial things
such as stuffing lists of people's phone numbers and e-mail addresses
into one ... (hm, I almost said "column" ... I guess "field" would be
more appropriate here). It would be nice to see an example of
something that would also scale comfortably beyond twenty rows or so.

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com


Reply With Quote
  #34  
Old   
David Cressey
 
Posts: n/a

Default Re: MV Keys (was: Key attributes with list values) - 02-26-2006 , 02:43 PM




"Bob Hairgrove" <invalid (AT) bigfoot (DOT) com> wrote

Quote:
On 26 Feb 2006 08:19:50 -0800, "Marshall Spight"
marshall.spight (AT) gmail (DOT) com> wrote:

mAsterdam wrote:
dawn wrote:
... What does it mean that a list is a key? If
I change one value in the list, does that make it a new key? I would
think so.

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)

Sure. If you change the order of the bits in the int,
that makes it a new key as well.

If you make a logical change to the value, it's a different value.
(Likewise, if the logical value stays the same but something
else changes, it's the same value.)

It's not quite that simple. As David pointed out, a "mushroom and
onion pizza" is not necessarily different than an "onion and mushroom
pizza". But the ordering of the bits in an integer is significant,
whereas the ordering of ingredients for a pizza isn't (although I'd
definitely want to make the crust before I put the tomato sauce on
it<g>).

Thank you.

There is a way to implement sets as bit strings, where the bit number
indicates which element of the universal set we are talking about and a
value means inclusion for a 1 and exclusion for a zero. This is basically
how Pascal implemented sets.

And, in this notation, a pizza with onion and mushroom has the same
representation as a pizza with mushroom and onion. So, if the original
order meant something, that information has been lost.

The way Pick (and I presume most of the MV family) represent lists is
inherently ordered. And, whenever I ask Dawn, or any of the other Pickies
who dorp in form time to time whether the order in a list conveys
information or not, the answer is always the same:
"the programmer knows what the data means".

The whole reason I got involved with databases, some twenty years ago, is to
have a more formal and explicit handle on what the data means. As Marshall
has pointed out, the semantics of the data are less than totally clear even
in the RDM. But it's considerably closer to self describing data than just
"ask the programmers".





Reply With Quote
  #35  
Old   
Bob Hairgrove
 
Posts: n/a

Default Re: MV Keys (was: Key attributes with list values) - 02-26-2006 , 02:45 PM



On Sun, 26 Feb 2006 20:47:05 +0100, Bob Hairgrove
<invalid (AT) bigfoot (DOT) com> wrote:

Quote:
It would be nice to see an example of
something that would also scale comfortably beyond twenty rows or so.
.... i.e., twenty phone nos. per person...

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com


Reply With Quote
  #36  
Old   
mAsterdam
 
Posts: n/a

Default Re: MV Keys - 02-26-2006 , 02:46 PM



Bob Hairgrove wrote:
Quote:
Marshall Spight wrote:

mAsterdam wrote:

dawn wrote:

... What does it mean that a list is a key? If
I change one value in the list, does that make it a new key? I would
think so.

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)

Sure. If you change the order of the bits in the int,
that makes it a new key as well.

If you make a logical change to the value, it's a different value.
(Likewise, if the logical value stays the same but something
else changes, it's the same value.)


It's not quite that simple. As David pointed out, a "mushroom and
onion pizza" is not necessarily different than an "onion and mushroom
pizza".
If it is we have a list of toppings.
If it isn't we have a set of toppings.

(David was sighing about some *very* long
winding threads about this).

Quote:
But the ordering of the bits in an integer is significant,
whereas the ordering of ingredients for a pizza isn't (although I'd
definitely want to make the crust before I put the tomato sauce on
it<g>).

One of the fundamental things in RM is that the Cartesian join of two
relations is commutative. Think about the implications of this when
trying to decide what requirements a MV key would have to fulfill.
If it is possible to define a generic macro (or as Date calls
it 'shorthand'), which expands/rewrites the relation with a MV key
into a set of relations with only single value keys, the
commutativity is not lost in the result.

I suspect that this is easier for set-keys than for list-keys.

Quote:
In Joe Celko's book "SQL for Smarties", there is an example of a
schema for an airline scheduling system which he uses to illustrate
DKNF (starts at the bottom of p. 35). How would someone model this in
a MV database? In this and similar threads here, when people talk
about the virtues of MV vs. RM, there is a perceived (by me) lack of
any real-world examples on the MV side that go beyond trivial things
such as stuffing lists of people's phone numbers and e-mail addresses
into one ... (hm, I almost said "column" ... I guess "field" would be
more appropriate here). It would be nice to see an example of
something that would also scale comfortably beyond twenty rows or so.
Disclosure: The only things I know about MV databases is from what Dawn
and some (other?) pick adepts tend to write about it in c.d.t.

In the current discussion I read for 'MV Key' simply Multiple-valued
key: an identification consisting of an arbitrary number of values.


Reply With Quote
  #37  
Old   
Bob Hairgrove
 
Posts: n/a

Default Re: MV Keys (was: Key attributes with list values) - 02-26-2006 , 03:21 PM



On Sun, 26 Feb 2006 20:43:46 GMT, "David Cressey"
<dcressey (AT) verizon (DOT) net> wrote:

Quote:
The way Pick (and I presume most of the MV family) represent lists is
inherently ordered. And, whenever I ask Dawn, or any of the other Pickies
who dorp in form time to time whether the order in a list conveys
information or not, the answer is always the same:
"the programmer knows what the data means".
This is a recipe for disaster, even in small-scale systems with a
lifetime of little more than a year or so. And we haven't even begun
to talk about security issues which is one of the main advantages of
using a good RDBMS.

I was involved with the Swiss census in the year 2000 writing stored
procedures for the main database. Although Switzerland is a relatively
small country compared to many, and the data didn't quite reach
teradata dimensions, we had over 100 tables IIRC, some with 10 to 20
million rows constantly being written to and read from by over 100
client PC operators simultaneously. The data went through several
stages, beginning with the data capture (mostly scanning paper forms
with some internet input), validation against prior household data
supplied by the communities, automatic processing (nightly batch jobs)
and manual processing (PC operators) until the final stage was
reached. Conceptually, there were at least four different schemata
involved, one of which was an entirely different database (and RDBMS)
whose data was transferred at night by batch jobs.

The programmers changed several times, even before the project was
finished. But the data is still being mined today, and I would hate to
think what would happen if some newbie application programmer were
allowed to change even one table, index or constraint. When I was
writing code for the batch processes, we had to use an API in order to
perform any DML at all. No one except for the team of DBA's had direct
access to any of the tables except for read-only access. ALL writes
were done through packages. And it was a good thing, believe me (even
though I had to beg for two months for an additional index before the
powers-that-be finally let me have it).

There are performance issues that MV databases probably cannot address
.... but I can't say for myself because I never worked with one. Take
clustering or partitioned tables: what do existing MV products have to
offer here? How do they implement user access rights? Roles?
Transactions? Backup and recovery? These are important issues. The
elegant thing about a good RDBMS is the fact that almost everything
can be implemented through system tables, i.e. RM.

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com


Reply With Quote
  #38  
Old   
Christopher Browne
 
Posts: n/a

Default Re: MV Keys - 02-26-2006 , 03:49 PM



After takin a swig o' Arrakan spice grog, mAsterdam <mAsterdam (AT) vrijdag (DOT) org> belched out:
Quote:
David Cressey wrote:
"mAsterdam" <mAsterdam (AT) vrijdag (DOT) org> wrote

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)
In other words, an onion and mushroom pizza is different from a
mushroom and
onion pizza.
Here we go again.

Yeah, ehrm well... Is this issue closed? Is there a nice solution?

In e.g. XML the basic assumption is that order has meaning, in SQL
it is that order has no meaning. Historically (XML coming from a
document heritage, SQL from experiments with relational products)
this makes sense, but I would prefer it if one could choose wether
order is meaningful/worth preserving/relevant or not - instead of
being pushed into one way of thinking or another because of the
background of the product at hand.
Is it *always* true, in XML, that order has meaning?

I don't think that's so at all...

There may exist cases where relative order can have meaning, but there
certainly exist cases where it is irrelevant.

For instance, RFC 3733 describes an XML schema for representing
contact information (the sort of information that the WHOIS service
reports for the various sorts of organizational contacts).

In that schema, order is normally expressly NOT significant in
indicating meaning.

If an XML request for creating a contact submits the <contact:name>
before or after the <contact:country>, that is entirely irrelevant as
far as any application is concerned.

More pointedly, the domain representation, in RFC 3731, can associate
multiple nameservers with a domain.

The canonical example is:
<domain:ns>
<domain:hostObj>ns1.example.com</domain:hostObj>
<domain:hostObj>ns2.example.com</domain:hostObj>
</domain:ns>

You might perceive an ordering, there; that ordering is not a real
one. That is, in formal terms, a set of nameservers. They are NOT
ordered, as far as the DNS service is concerned.

I'm sure you can find counterexamples; what that would establish is
not that "order always has meaning" in XML, but rather that
*sometimes* the order of elements in an XML document has meaning.

In effect, you don't have the result you wish you had; in order for
order to be preserved, when it important to do so, it is vital to
expressly declare that it needs preservation. XML doesn't help as it
does not provide any way to systemically indicate that need.
--
output = ("cbbrowne" "@" "gmail.com")
http://linuxdatabases.info/info/spreadsheets.html
In MDDT, no one can hear you scream...
But everybody can hear you say "whoops!"


Reply With Quote
  #39  
Old   
Brian Selzer
 
Posts: n/a

Default Re: Key attributes with list values was Re: What are the differences ...KEY - 02-26-2006 , 03:51 PM



You asked for an example, so here goes.

Consider the following set of propositions:

Jane Harper is married.
Jane Smith is single.

And a constraint that states that single people cannot become divorced.

Now, imagine that you're the database, and that you've been presented with
the following set of values to replace the above set:

Jane Harper is married.
Jane Smith is divorced.

Do you reject the update?

The problem is that there is no way for you to know that Jane Harper in the
first set is the same person in the second set. For example, in the
original set, Jane Harper's maiden name may be Smith, and Jane Smith may
have married Paul Harper. It is impossible for you to know because that
information was not provided. Because the update is set-based (and must be,
since either update taken individually would violate the primary key
constraint), and because the only key can change, it is not possible to
enforce the transition constraint because there isn't any mechanism to
correlate the propositions in the first set with the propositions in the
second.

Also see comments inline.

"Marshall Spight" <marshall.spight (AT) gmail (DOT) com> wrote

Quote:
Brian Selzer wrote:
"Marshall Spight" <marshall.spight (AT) gmail (DOT) com> wrote in message
What I'm trying to convey is that from one point of view, a list
has identity, regardless of its contents.

I reject this point of view. The system I am building has values
and variables only. There are no pointers, there are no addresses,
and there is no concept of identity. There is only value.

What about the list of operations and materials that are required to
produce a part? That certainly has identity.

Nope. Just a value. Same as an int.


This is not to say that the concept of identity is not consistent.
It certainly is, and useful programming languages have been
built on top of it. It is foundational to OOP. However, useful
systems have been built without it as well; it is not a necessary
concept.

I disagree. It is a necessary concept, not only externally but also
internally.

There are plenty of useful general purpose programming languages
that don't have any concept of identity in them. Mercury, for
example. (And in the non-general-purpose category, SQL.)
So I don't see how you could describe the concept as "necessary."
Useful, arguable, but not necessary. A turing machine doesn't
have any notion of identity. The lamba calculus has no notion
of identity. Come to that, the lambda calculus has no concept
of equality, either. Huh. So I guess neither one is necessary.

I'm not sure we're using the terms in the same way, though.
Do you speak Java?

Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j); // tests for identity
System.out.println(i.equals(j)); // tests for equality

Is that how you're using the terms?

In Java, == on a reference type tests for reference equality,
which is to say identity. If there were no reference types,
as in Prolog or SQL or whatever, then there is no identity.

That's the point: a non-1NF attribute is not scalar, hence the ambiguity.

Quote:
An entity must have identity, otherwise there's no way for the
database, or users, for that matter, to distinguish between them.
That's the whole point of keys.

One distinguishes between values by equality. If two values
are equal, they are the same value. If they are not equal,
they are not the same value. This is true for key values as
well as nonkey values.


Keys work because one can compare values, not because
one can compare identies. That is the fundamental difference
between keys and pointers.
I disagree, and the example above bears me out. The knowledge represented
in a database is subject to the universe of discourse, and as such only
those attributes that belong to that universe are available to the database.
The example above shows that an entity represented in a proposition in one
database state may not necessarily be the same entity represented by a
proposition in a later database state even if the attribute values are
identical.

Quote:
Members of a set don't have identity.

Yes they do. Is a roll of quarters worth 25 cents? No, and to elucidate
upon my previous point, the attributes that would uniquely identify each
individual quarter may not be relevant within the universe of discourse, but
that doesn't change the fact that there are still 40 quarters.

Quote:
Because a key value determines all other attribute
values, it identifies an entity.

Sure. This requires only values and equality.


But a there's a problem: a key value may
change over time, so any given key value's ability to determine what was
or
is known about an entity is limited to a specific interval, bounded by
the
time that its value became known by the database and the time that a new
value became known. This imposes limitations on the types of updates
that
can be performed or the types of constraints that can be enforced.

Um, I don't see how it does. If you want to impose specific semantics
on the data, then that might constain how you allow the data to be
updated. But that is true of any constraint. Constraints are semantic
things; values are logical things. 240 is a perfectly legal int, but it
might not be an allowed age for a person.

Have you tried writing a trigger to audit changes to rows in a table that
has only natural keys in SQL Server? Then you've seen the code that's
required to prevent multi-row updates that also affect a column that is part
of the key.

Quote:
If all
keys can change, then either updates must be singular, that is, must
affect
only one entity of any given type at a time, or no temporal constraint (a
constraint that involves the state of the database at more than one point
in
time) can be enforced.

I don't see why this should be so. Perhaps I'm just not following your
terminology. And anyway, if your domain wants keys that don't change,
just apply a constraint that enforces that.

That is not always possible for natural keys, or even for composite keys.

Quote:
This is a significant limitation of the Relational
Model with which I am most familiar, but I suspect that the concept
applies
to all other data models, which may have means to overcome it. In the
Relational Model, all updates are set-based, and if all keys are subject
to
change during an update and if the cardinality of the update is greater
than
one, then there's no way to determine which tuple in a new relation value
corresponds to any given tuple in the original relation value.

I don't see how you can use the word "limitation" to describe
what you appear to consider the ability to update too much.
Assuming you add code to reject these updates you don't
like, would you say that you had "removed a limitation"?

The limitation is that you can't write code to reject these updates without
also rejecting perfectly valid updates, unless you do it in the application.

Quote:
Also, I think you somewhat overstate the case. If I have
a relation of customers with customerid in the range 1 - 1000,
and I decide I want customer ids to start at 1,000,000, I can
"UPDATE Customers set CustomerId = CustomerId + 1000000;"
and there's an update that changes keys and has
cardinality greater than one, and I can still determine
which tuple in the new relation value corresponds to any
given tuple in the original relation value.

But that's because in this case you can detect a pattern between the values.
That is not always possible, and besides, it requires that the system probe
the right-hand side of the assignment in order to find some means to
correlate tuples. Not only is that not practical, as the example above
shows, it is not always possible.

Quote:
If you want a system that supports identity, you don't want to
be using set theory. There are plenty to choose from, and
they are well-supported and popular!

Yes, I do want to be using set theory. The recognition of identity does not
alter the sound theoretical foundation that the Relational Model provides.
It strengthens it, or better yet, completes it.

Quote:
It should be obvious that correlation is necessary to enforce
a constraint that involves more than one database state.

It's not obvious to me.

Obviously.

Quote:
Every proposition must
necessarily be different from every other proposition, because either
something is known, or it isn't: the knowledge contained in a database is
a
set of propositions, not a collection. Thus every proposition has
identity
with respect to the state of the database at any specific point in time,
and
that identity can be revealed as an attribute.

If what you're saying here is "every relation must have at least one
key"
then I agree. If that's not what you're saying, then I don't
understand.


In order to avoid losing
information over time, every new proposition must have a new identity
value.

In this and in the previous part, it appears you are using the term
"identity value" as a synonym for key. Is that correct?

No. It is not. Every proposition in the entire database must be distinct
from every other proposition and thus has identity with respect to the
database, regardless of whether those propositions are organized into
relations, some multi-valued construct or whatever else. An identity value
is a representation of a proposition's identity with respect to the entire
database. If the database is organized into relations, then an identity
attribute is clearly a candidate key on any relation that reveals it, but
conceptually, its value must be distinct throughout the database, not
limited to the scope of a single relation.

Quote:
By that I mean that new values exist only for propositions that are
completely new to the database rather than to propositions that have been
changed. In other words, something can become known by the database, and
something that is already known can change. The distinction is subtle, I
know, but necessary--especially in a temporal database, but also in one
that
only requires that transitions be constrained.

Perhaps an example is in order.


Marshall




Reply With Quote
  #40  
Old   
mAsterdam
 
Posts: n/a

Default Document order (was: MV Keys) - 02-26-2006 , 05:00 PM



Christopher Browne wrote:
Quote:
After takin a swig o' Arrakan spice grog, mAsterdam belched out:
Cheers!

Quote:
David Cressey wrote:

mAsterdam wrote:

If I change the order of the items in the list,
does that make it a new key? I would think so. (See below)

In other words, an onion and mushroom pizza is different from a
mushroom and
onion pizza.
Here we go again.

Yeah, ehrm well... Is this issue closed? Is there a nice solution?

In e.g. XML the basic assumption is that order has meaning, in SQL
it is that order has no meaning. Historically (XML coming from a
document heritage, SQL from experiments with relational products)
this makes sense, but I would prefer it if one could choose wether
order is meaningful/worth preserving/relevant or not - instead of
being pushed into one way of thinking or another because of the
background of the product at hand.


Is it *always* true, in XML, that order has meaning?
No. Coming from a document background, its *basic* assumption is
that order is significant.

At http://www.w3.org/TR/xpath Chapter 5, Data Model
says: "There is an ordering, document order, defined on all the nodes in
the document corresponding to the order in which the first character of
the XML representation of each node occurs in the XML representation of
the document after expansion of general entities. "


Quote:
I don't think that's so at all...

There may exist cases where relative order can have meaning, but there
certainly exist cases where it is irrelevant.

For instance, RFC 3733 describes an XML schema for representing
contact information (the sort of information that the WHOIS service
reports for the various sorts of organizational contacts).

In that schema, order is normally expressly NOT significant in
indicating meaning.

If an XML request for creating a contact submits the <contact:name
before or after the <contact:country>, that is entirely irrelevant as
far as any application is concerned.
Of course. The application can rely on the parser to extract the
attributes based on the name. However, does the a change in the order
of contacts constitute a different document? AFAIK it does.

Quote:
More pointedly, the domain representation, in RFC 3731, can associate
multiple nameservers with a domain.

The canonical example is:
domain:ns
domain:hostObj>ns1.example.com</domain:hostObj
domain:hostObj>ns2.example.com</domain:hostObj
/domain:ns

You might perceive an ordering, there; that ordering is not a real
one. That is, in formal terms, a set of nameservers. They are NOT
ordered, as far as the DNS service is concerned.

I'm sure you can find counterexamples; what that would establish is
not that "order always has meaning" in XML, but rather that
*sometimes* the order of elements in an XML document has meaning.
Or: Unless special care has been taken to take it out, order in a
document has meaning.

Quote:
In effect, you don't have the result you wish you had; in order for
order to be preserved, when it important to do so, it is vital to
expressly declare that it needs preservation. XML doesn't help as it
does not provide any way to systemically indicate that need.
How do you declare that it needs preservation?
I was under the impression that query results were in document
order - but please correct me if I'm wrong.


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.