The at-scale way to do it is a database with full description (so you can find e.g. resistor, fixed, 112k, 1%, 1/8W, 0805), which links to a single symbol and a single footprint, which has been vetted, checked carefully against not just the datasheet but also tested in production.
Component creation is not to be taken lightly here, and should be reviewed by several engineers before finalizing into the production database. This is an onerous step, but the payoff is, once you have 99% of common parts types, you don't have to think about using any of them, just plop them in and go. You'll be creating variants of resistors and capacitors forever, but parts within an existing family are a no-brainer.
The downside is, it's impossible to edit such a database. Even if you make changes, it's not like they will magically push to every existing schematic. So consistency can be a headache.
This of course doesn't affect production boners; the AVLs are separate from this (or, maybe more columns in the same database, but updated from time to time) and need to be checked and re-checked in their own process.
Personally, as my database is smaller and only used by myself, I use one common SchLib and one common PcbLib, that's it. I keep generic parts generic in the library, and set their value and part number on the schematic instead. I put part numbers in for specific items (ICs for example) that I won't have any reason to change later on the schematic. This tends to cause more repeated operations (setting part numbers), or copying from existing schematics (if I happen to remember using a particular value and part elsewhere), which isn't a big deal as the time spent doing that is rolled into shopping for prototype parts anyway (basically, I don't need to use a particular resistor until I've purchased it). Clearly this is a less production-oriented approach, and that's fine as most of my customers expect to do production and maintenance themselves.
Tim