Самый простой способ понять, почему лучше использовать «более плоскую» структуру, - это посмотреть, как вы ее защищаете и как реализовать функциональность.
Ваша первая структура:
users: {
uidOfJacob: {
stackId: 884522,
ssn: "999-99-9999",
profile: {
displayName: "Jacob Philips"
}
},
uidOfPuf: {
stackId: 209103,
ssn: "999-99-9999",
profile: {
displayName: "Frank van Puffelen"
}
}
}
Вы обеспечили бы его с помощью:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
"profile": {
".read": true
}
}
}
}
}
. Одна из основных причин наличия публичной информации - показать список этой информации. В JavaScript:
ref.child('users').child(???).child('profile').on('child_added'...
Это не сработает, потому что мы помещаем ???
. Операции Firebase должны иметь возможность читать весь список из одного места, и пользователю необходимо иметь разрешение на чтение во всем этом местоположении (а не только на отдельные дочерние узлы).
Если мы структурируем данные для отделите общедоступную информацию от частной информации, мы получим:
users: {
uidOfJacob: {
stackId: 884522,
ssn: "999-99-9999",
profile: {
displayName: "Jacob Philips"
}
},
uidOfPuf: {
stackId: 209103,
ssn: "999-99-9999",
profile: {
displayName: "Frank van Puffelen"
}
}
},
"profile": {
uidOfJacob: {
displayName: "Jacob Philips"
},
uidOfPuf: {
displayName: "Frank van Puffelen"
}
}
Вы обеспечили бы ее с помощью:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
},
"profiles": {
".read": true,
"$uid": {
".write": "auth.uid == $uid"
}
}
}
}
Не получать список профилей публичных пользователей, вы будете делать:
ref.child('profiles').on('child_added'...
Это будет работать, потому что у всех есть разрешение на чтение на profiles
.
?copy
в версии 1.9.3. Из NEWS : blockquote>
- Перемещено
?copy
на свою страницу справки и задокументировано, чтоdt_names <- copy(names(DT))
необходимо, чтобыdt_names
не был изменен ссылку в результате обновленияDT
по ссылке (например: добавление нового столбца по ссылке). Закрывает # 512 . Благодаря Zach для этот вопрос SO и user1971988 для этот вопрос SO .
Часть вашего первого вопрос делает для меня немного непонятным относительно того, что вы действительно имеете в виду относительно оператора
<-
(по крайней мере, в контекстеdata.table
), особенно для части: . В других случаях мы явно предупреждают, что & lt; - создает копии, как data.tables, так и data.frames.Итак, прежде чем отвечать на ваш реальный вопрос, я кратко коснусь его здесь. В случае
data.table
a<-
(присвоение) просто недостаточно для копирования adata.table
. Например:DT <- data.table(x = 1:5, y= 6:10) # assign DT2 to DT DT2 <- DT # assign by reference, no copy taken. DT2[, z := 11:15] # DT will also have the z column
Если вы хотите создать
copy
, вы должны явно указать его с помощью командыcopy
.DT2 <- copy(DT) # copied content to DT2 DT2[, z := 11:15] # only DT2 is affected
From CauchyDistributedRV, Я понимаю, что вы имеете в виду назначение
names(dt) <- .
, которое приведет к предупреждению. Я оставлю это как таковой.
Теперь, чтобы ответить на ваш первый вопрос: похоже, что
names1 <- names(DT)
также ведет себя аналогично. Я до сих пор не думал об этом. Здесь очень полезна команда.Internal(inspect(.))
:.Internal(inspect(names1)) # @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100) # @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x" # @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y" .Internal(inspect(names(DT))) # @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100) # @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x" # @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y"
Здесь вы видите, что они указывают на ту же ячейку памяти
@7fc86a851480
. Дажеtruelength
изnames1
равно 100 (по умолчанию выделено вdata.table
, для этого нужно проверить?alloc.col
.truelength(names1) # [1] 100
Таким образом, назначение
names1 <- names(dt)
кажется происходят по ссылке. То есть,names1
указывает на то же место, что и указатель имен столбца dt.Чтобы ответить на ваш второй вопрос: команда
c(.)
, похоже, создает копию , поскольку нет проверки того, что результат содержимого из-за операции конкатенации различен . То есть, поскольку операцияc(.)
может изменять содержимое вектора, это немедленно приводит к тому, что «копия» сделана без , проверяя, не изменяется ли содержимое.
.Internal(inspect())
. Наверное, я не понял, что базовые векторы i> могут быть внутренне привязаны кdata.table
- я всегда думал, что толькоdata.table
может быть внутренне ссылкой наdata.table
, – Zach 9 April 2013 в 23:32names
не копировать вектор при назначении? Кроме того, я предполагаю, что возникла путаница, потому чтоnames<-.data.table
действительно вынуждает копию, следовательно, функциюsetnames
. Мое предположение: это связано с тем, какdata.table
играет с подсчетом ссылок. – Kevin Ushey 10 April 2013 в 05:48:=
назначает новый столбец, он также обновляет вектор имен по ссылке. Это может быть изменено / исправлено, если не перераспределить вектор имен. Но тогда это будет немного медленнее, если добавить столбцы в цикл. Поэтому, возможно, лучше документировать, что требуетсяnm <- copy(names(DT))
, иначеnames(DT)
возвращает ссылку. – Matt Dowle 10 April 2013 в 10:16copy
, когда ожидается, что копия будет репликой. Что касается источника проблемы, я вполне уверен, что это связано с ленивой оценкой<-
. См. Это (дублировать!) Сообщение: stackoverflow.com/a/16543387/1492421 – Ricardo Saporta 14 May 2013 в 16:14