1 thing to note, the ID get fucked up if player are not placed in team in the same order they joined the server.
Let say we got 2 player A, B
B join the game, A join the game A join team Dire, B join Team Radiant, A ID will be 1 but in data storage he is 0 while B ID is 0 but data storage is 1.
If B join the game, A join the game, B join team Dire, A join Team Radiant, A ID will be 1 and the data storage for dota will also be 1.
Player ID = order of player join.
Storage ID = order of player join a team.
EDIT: I've notice your issue. You have a UNIT ID which is kind of different, HEROs have different ID than players but they are owned by one. And just to make things even more clarify, a summoned unit will create new unit that the play is able to control but the owner will be the hero not the player. So here is a little snippet to get the root player owner.
/* GET THE ATTACKER */
int unit_owner = GetEntPropEnt(unit, Prop_Send, "m_hOwnerEntity");
/* UNIT CONTROLLED BY PLAYER OR A SUMMONED UNIT */
while (unit_owner >= 10)
unit_owner = GetEntPropEnt(unit_owner, Prop_Send, "m_hOwnerEntity");
if unit_owner == -1 it mean that the "player" owner is not a player (creeps, neutral, roshan)