这个问题的重点是弄清楚哪种技术更好,并听取了一些熟练的symfony2编码人员的不同意见。
将以挑战和“挑战等级”表为例,许多人可以对某些挑战进行评级。(类似于stackoverflow投票问题系统)。
这些表如下所示:(like_dislike是布尔值(1 =喜欢,0 =不喜欢)
挑战的数据量为10-200 +。
挑战实体
/**
* Challanges
*
* @ORM\Table(name="challanges")
* @ORM\Entity(repositoryClass="TB\ChallangesBundle\Entity\ChallangesRepository")
*/
class Challanges
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
* @Assert\NotBlank()
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="slug", type="string", length=255, unique=true)
*/
private $slug;
/**
* @var string
*
* @ORM\Column(name="description", type="text")
* @Assert\NotBlank()
*/
private $description;
/**
* @var \DateTime
* @ORM\Column(name="start_date", type="datetime", nullable=false)
* @Assert\DateTime()
*/
private $start_date;
/**
* @var \DateTime
* @ORM\Column(name="end_date", type="datetime", nullable=false)
* @Assert\DateTime()
*/
private $end_date;
/**
* @ORM\ManyToOne(targetEntity="TB\UserBundle\Entity\User", fetch="EXTRA_LAZY")
* @ORM\JoinColumn(name="owner_id", referencedColumnName="id", nullable=false)
*/
protected $owner;
/**
* @ORM\OneToMany(targetEntity="TB\ChallangesBundle\Entity\ChallangeRating", mappedBy="challange", cascade={"persist", "remove"})
*/
protected $likes;
/**
* Constructor
*/
public function __construct()
{
$this->likes = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add likes
*
* @param \TB\ChallangesBundle\Entity\ChallangeRating $likes
* @return Challanges
*/
public function addLike(\TB\ChallangesBundle\Entity\ChallangeRating $likes)
{
$this->likes[] = $likes;
return $this;
}
/**
* Remove likes
*
* @param \TB\ChallangesBundle\Entity\ChallangeRating $likes
*/
public function removeLike(\TB\ChallangesBundle\Entity\ChallangeRating $likes)
{
$this->likes->removeElement($likes);
}
/**
* Get likes
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getLikes()
{
return $this->likes;
}
public function filterLikesInChallenge($like_dislike) {
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('like_dislike', $like_dislike));
return $this->likes->matching($criteria);
}
public function checkIfUserRatedAlready(\TB\UserBundle\Entity\User $user)
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('fan', $user));
return $this->likes->matching($criteria);
}
挑战等级实体
<?php
namespace TB\ChallangesBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ChallangeRating
*
* @ORM\Table(name="challange_rating")
* @ORM\Entity(repositoryClass="TB\ChallangesBundle\Entity\ChallangeRatingRepository")
*/
class ChallangeRating
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var boolean
*
* @ORM\Column(name="like_dislike", type="boolean")
*/
private $like_dislike;
/**
* @ORM\ManyToOne(targetEntity="TB\UserBundle\Entity\User", inversedBy="fans")
*/
protected $fan;
/**
* @ORM\ManyToOne(targetEntity="TB\ChallangesBundle\Entity\Challanges", inversedBy="likes")
*/
protected $challange;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get like_dislike
*
* @return boolean
*/
public function getLikeDislike()
{
return $this->like_dislike;
}
/**
* Set like_dislike
*
* @param boolean $like_dislike
* @return ChallangeRating
*/
public function setLikeDislike($like_dislike)
{
$this->like_dislike = $like_dislike;
return $this;
}
/**
* Set fan
*
* @param \TB\UserBundle\Entity\User $fan
* @return ChallangeRating
*/
public function setFan(\TB\UserBundle\Entity\User $fan = null)
{
$this->fan = $fan;
return $this;
}
/**
* Get fan
*
* @return \TB\UserBundle\Entity\User
*/
public function getFan()
{
return $this->fan;
}
/**
* Set challange
*
* @param \TB\ChallangesBundle\Entity\Challanges $challange
* @return ChallangeRating
*/
public function setChallange(\TB\ChallangesBundle\Entity\Challanges $challange = null)
{
$this->challange = $challange;
return $this;
}
/**
* Get challange
*
* @return \TB\ChallangesBundle\Entity\Challanges
*/
public function getChallange()
{
return $this->challange;
}
}
好的,现在我要:
控制器
从获得挑战开始就如此经典
// this will take care of point number 1 (display challenge details) (1.)
$challange = $challangesRepo->findOneBy(array('slug'=>$slug));
// display numbers of likes and dislikes for certain challenge (2.)
但是现在有一个决定...
我应该通过从querybuilder中查询数据库来获得赞吗?(经典选择计数)
或者
我应该使用这样的集合和条件吗?:
$challangeLikes = $challange->filterLikesInChallenge(1);
$challangeDislikes = $challange->filterLikesInChallenge(0);
**什么是更好的内存使用率?什么对数据库性能更好?**
如果我没有记错的话,以下两个查询将通过这两个方法执行:
SELECT
t0.id AS id1,
t0.like_dislike AS like_dislike2,
t0.fan_id AS fan_id3,
t0.challange_id AS challange_id4
FROM
challange_rating t0
WHERE
(
t0.like_dislike = ? AND t0.challange_id = ?
)
Parameters: [1, 12]
SELECT
t0.id AS id1,
t0.like_dislike AS like_dislike2,
t0.fan_id AS fan_id3,
t0.challange_id AS challange_id4
FROM
challange_rating t0
WHERE
(
t0.like_dislike = ? AND t0.challange_id = ?
)
现在,我可以将喜欢,不喜欢的次数传递给视图,如下所示:
'challangeLikes'=>$challangeLikes->count(),
'challangeDislikes'=>$challangeDislikes->count(),
如果我想知道某些用户是否已经对此挑战进行评分,该怎么办?
再次...
*我应该使用带有选择计数的经典querybuilder样式吗*
或者
我应该使用类似的方法:
$ratedAlreadyCol = $challange->checkIfUserRatedAlready($user)->first();
那实际上会执行另一个查询吗?像经典的选择计数之类的东西,但是集合会帮我做这个吗?因此,这不是在所有具有大喜乐的大型内存阵列中进行搜索,而是对DB的查询?
SELECT
t0.id AS id1,
t0.like_dislike AS like_dislike2,
t0.fan_id AS fan_id3,
t0.challange_id AS challange_id4
FROM
challange_rating t0
WHERE
(
t0.fan_id = ? AND t0.challange_id = ?
)
Parameters: [25, 12]
我想展示所有“粉丝-评出特定挑战的人” ...
再次...
我是否应该在存储库中创建单独的querybuilder方法,并通过内部连接到用户表来选择某些挑战的所有评级(因此我可以显示个人资料图片和用户名)
或者
我是否应该获得所有收视率,并在树枝循环中像这样:
$challangeLikesCollection = $challange->getLikes();
{% for bla bla
如果我这样做的话...教义将为循环中的每个“粉丝”对用户表执行一个选择查询...并且何时会有这样的说法... 200粉丝...那不是很好吗?
能以某种方式请他提供处理这些情况的方法吗?有什么建议?
还是您使用其他任何技术?
我非常关心内存使用率和数据库加载时间,因为它将在任何地方使用,并且每个用户都会遇到这样的列表,并面临不同的挑战。清单将包括15个挑战,并将所有喜欢,不喜欢的事物与列表中的每个挑战联系起来,等等。
感谢您的解释,提示和提示,它们将帮助我和其他读者迈上另一个台阶!
我将执行以下操作:
非规范化一点,添加number of likes
和number of dislikes
领域Challenge
,并更新这些值addLike
和removeLike
重命名like_dislike
为,like
因为它是一个布尔字段,并且1表示喜欢0表示不喜欢
使用单独的查询来查询用户列表,并使用数组水化和INDEXBY用户名(它必须是唯一的或用户ID),或者可以创建自定义水化器
选择u.username,u.photo从用户u INNER JOIN用r.fan = u进行评估u.username
或类似的东西。并且您可以检查当前用户的用户名是否在数组中。
我认为这可能足够出色。
一些解释:
INDEX BY表示结果集合或数组键(索引)将是一个字段的值(此字段必须是唯一的)。当您使用INDEX BY时,结果集将包含已知键,因此您可以在恒定时间内直接获取(例如检查是否存在)单个结果(不必搜索整个结果集)。
Doctrine在下面使用PDO,水合作用意味着如何处理PDO结果集并将其转换为其他内容。默认的对象水合意味着将结果集转换为对象图,这是非常昂贵的操作。还有其他一些较便宜的水合作用模式,但是您失去了易用性。例如,如果您使用数组水合作用,那么结果将是一个数组数组,因此您无法对其进行修改(我的意思是将其持久化回到数据库中),因此它仅用于读取,结果不是实体对象,因此您无法使用其方法,例如自定义吸气剂。您可以根据需要创建自定义水龙头。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句