Is a simple question, but I want to understand this at the low level.
Since the UTXO is a database with the yet-to-be-spent coins, how can I say that a given coin was already full spent? What would be a "half"-spent coin (if this is even possible)?
An output ("coin") is by definition either fully unspent or completely spent. There is nothing in between. A transaction has one or more inputs (which refer to the unspent outputs of earlier transaction) and it fully consumes them.
A transaction can also have 1 or more outputs. For each output a value is specified (number of Satoshis), so by being a little creative you can easily split or merge "coins".
This way Bitcoin "simply" needs to remember only the last outputs of a chain of transactions, there is no point in remembering (indexing) anything older. That's what the UTXO set is: Unspent Transaction Outputs database.
UTXO can only be spent completely.
This happens by claiming them in the Transaction Input Script and requires a valid signature corresponding to the address the UTXO is associated with.
The transaction inputs' value is then reassigned by the transaction to create new unspent transaction outputs. Usually, there are at least two outputs, one going to the recipient of the payment, and a change output going back to the wallet of the sender. The sum of the assigned outputs must be smaller than or equal to the sum of consumed inputs.
Any amount that doesn't get assigned to new outputs can be claimed by the successful miner as transaction fee in the Coinbase transaction of the block the transaction gets included in.
When a block gets found, all nodes in the network enact all the transactions on their UTXO set, marking the inputs as spent and replacing them with the newly minted unspent transaction outputs.
Besides the whole blockchain database there is actually another database continuosly updated in each full node: The UTXO pool memory. When a transaction with a determined input sucesfully spend some transaction output, this outpus is removed from the UTXO pool memory. Otherwise the handle of the databases to find if a given UTXO hasn't been called by any input of any transaction included in the blockchain would be strenuous. Remember that an UTXO can only be spent once and you have to enable the verify engine to quickly check whether an UTXO is still available for spending by any future input.