You have a physical layer of schema that enforces data types, keys, relationships, things like that. This is where you typically enforce things like making sure that a price is always a number, not a string or a date or a BLOB, and also where you enforce that every product should have a price.
Then there's the logical schema. At minimum, your semantics end up existing here, but oftentimes there are also other written or unwritten rules that the DBMS itself isn't enforcing. It's possible to set up constraints to ensure that a one-to-many relationship is actually a one-to-at-least-one relationship, for example, but I don't see it happen often in practice - those rules are only enforced by the application. Or you'll often see structures where one field's value is interpreted differently depending on the value of another field - essentially, creating a union type in the database. This is typically done in the logical schema, not the physical schema, because most people find it annoying to write the constraints you need to ensure that the DBMS itself is enforcing those rules.
When you have multiple applications accessing the DB directly, it's common for all of them to implement a slightly different version of the logical schema. At which point you might have a plethora of different schemas co-existing within the same database. For better or for worse.
Yes. OTOH, with NoSQL you have no authoritative schema; your code may allow for multiple different schemas, and your records may have multiple different schemas, and they could agree or disagree to any extent.
OTOH, `\d users` in PostgreSQL is authoritative; there cannot be a row that does not conform to the fields, types, and constraints listed there.
I think the word you're looking for is "enforced". Where there are multiple schemas, one can certainly be the "authority", even if it's not enforced across all data.
I generally agree with you, though. In my ideal world, people working on the batch, offline processing, etc. would be integrating through a centralized API...
Classic example being that our code used visibility_score but a tool was adding a visibilityScore property to every document as part of a cron job calculation.
If you generate your model/domain based on the underlying database schema then you effectively have a single view of the world, one that will ideally blow up at compile time (if your language is statically typed) when the database schema changes.
It's not perfect, if someone changes the schema in production then you're SOL, but at least it brings some sanity to the table vs. NoSQL where you simply have no idea what the state of the world is until you run your program.
F# Type Providers are probably the gold standard wrt to binding schema to application code, but any code generation library will provide similar benefit.